【问题标题】:LoadLibrary fails to load C++ CLI created dllLoadLibrary 无法加载 C++ CLI 创建的 dll
【发布时间】:2013-06-18 09:48:30
【问题描述】:

我在 Visual Studio 2010 中使用 CLR 选项创建了一个 c++/cli dll,如下所示,并创建了 email.dll。然后为了测试这一点,创建了另一个 vs2010 win32 项目并尝试使用 LoadLibrary 加载 email.dll,它总是返回 NULL:

HINSTANCE hGetProcIDDLL = LoadLibrary((LPCWSTR)"pathto\\email.dll");

我的问题是:应该以其他方式加载 email.dll 吗?或者如果 email.dll 创建不正确。

email.cpp 的 C++/CLI 代码:定义 DLL 应用程序的导出函数。

#using <mscorlib.dll>
#using <system.dll>
include "stdafx.h"
using namespace System;

using namespace System::Net::Mail;


extern int CallSendEmailFromGmail(char* fromEmail, char* password, char* toEmail, char* subject, char* message);


extern "C"
{
     __declspec(dllexport) int SendEmailFromGmail(char* fromEmail, char* password, char* toEmail,    char* subject, char* message)
    {
        return CallSendEmailFromGmail(fromEmail, password, toEmail, subject, message);
    }

}

int CallSendEmailFromGmail(char* fromEmail, char* password, char* toEmail, char* subject, char* message)
{

        String ^from = gcnew String(fromEmail); 
        String ^pwd = gcnew String(password);
        String ^to = gcnew String(toEmail);
        String ^subjectStr = gcnew String(subject);
        String ^messageStr = gcnew String(message);
        SmtpClient ^client = gcnew SmtpClient();
//    client->DeliveryMethod = SmtpDeliveryMethod.Network;

      client->UseDefaultCredentials = false;
      client->Credentials = gcnew System::Net::NetworkCredential(from, pwd);
      client->Port = 587;
      client->Host = "smtp.gmail.com";
      client->EnableSsl = true;
      MailMessage ^mail = gcnew MailMessage(from, to);
      mail->Subject = subjectStr;
      mail->Body = messageStr;
      try
       {
           client->Send(mail);
       }
       catch (Exception ^ex)
       {
           Console::WriteLine("Message : " + ex->Message);
           return 1;
        }

        Console::WriteLine("Message : Done" );
        return 0;
 }

【问题讨论】:

  • 你需要改掉使用强制转换的习惯,让编译器不再告诉你你做错了。 (LPCWSTR) 只会阻止编译器抱怨,它并没有阻止你做错事。您在字符串文字前加上 L 以使其成为宽字符串,例如 L"This is a wide string"。使用 LoadLibrary() 也是错误的,您使用 Assembly::LoadFrom() 来加载托管程序集。它没有什么意义,只需添加对程序集的引用,以便 CLR 自动为您加载 DLL。
  • @HansPassant 他正在测试他的导出函数入口点。

标签: c++-cli


【解决方案1】:

当 Win32 API 函数失败时,它通常会为线程设置错误代码。所以,说函数返回 NULL 是不够的。 LoadLibrary 文档将您指向 GetLastError 文档。

这可能是问题所在:

LoadLibrary((LPCWSTR)"pathto\\email.dll");

您不能强制转换以更改文件路径的字符串表示。您似乎定义了 UNICODE,这很好;您最终将调用 LoadLibraryW 而不是 LoadLibraryA。要为 LoadLibraryW 构造文件路径,请使用:

LoadLibraryW(L"pathto\\email.dll");

【讨论】:

  • 同意;谢谢。理想情况下,我们会使用u"pathto\\email.dll",因为这正是 LoadLibraryW 所需要的。但今天不支持。
  • 非常感谢它对我有用!我现在可以通过 email.dll 中的一项更改来调用导出的函数,该更改使用 #pragma unmanaged 和 #pragma managed 在 dllMain 周围,因为测试项目是在没有 clr 的情况下构建的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多