【发布时间】:2010-09-09 19:37:49
【问题描述】:
我从第三方供应商处获得了一个用 Visual Basic 创建的 DLL(Sensor DLL.dll)。这个 DLL 包含与传感器通信的函数,我需要从我正在编写的 Visual C++ 程序中调用这些函数。供应商不会提供头文件,而且我不知道 Visual Basic。如果我有一个头文件,这将是一个 15 分钟的项目......相反,一周后我仍在努力解决它。请帮忙!
有人告诉我 DLL 中的一个函数 (Get_Data) 的形式是:
Public Function Get_Data(ByVal Handle As String) As String
我尝试了几种方法来调用这个 Get_Data 函数,但都没有成功:
方法一) DllImport 属性
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
namespace Sensor
{
[DllImport("Sensor DLL.dll", EntryPoint = "Get_Data", CharSet = System::Runtime::InteropServices::CharSet::Unicode)] BSTR Get_Data(BSTR 句柄); }
//then I call the function
Sensor::Get_Data(Handle);
这种方法似乎是我得到的最接近 sloution 的方法。它可以编译,但运行时会出现以下错误:
发生了“System.EntryPointNotFoundException”类型的未处理异常
附加信息:无法在 DLL“Sensor DLL.dll”中找到名为“Get_Data”的入口点。
我尝试了除 BSTR 之外的各种数据类型组合/排列,包括 BSTR*、wchar_t、int 等。可能我错过了一个,但每种数据类型都返回相同的错误。
方法二) dllimport 存储类属性
__declspec(dllimport) BSTR Get_Data(BSTR Handle);
//then I call the function
Get_Data(Handle);
这种方法让我感到困惑,因为我没有指定要从中导入的 DLL。我已将 DLL 复制到项目文件夹并手动将其添加到项目中,因此希望这意味着可以找到它。当我编译链接器返回以下错误:
错误 LNK2028:函数“int __cdecl main(void)”(?main@@$$HYAHXZ)
错误 LNK2019:函数“int __cdecl main(void)”(?main@@$$HYAHXZ) 中引用了无法解析的外部符号“wchar_t * __cdecl Get_Data(wchar_t *)”(?Get_Data@@$$FYAPA_WPA_W@Z)
我怀疑这可能意味着我应该使用 wchar_t 或 wchar_t* 而不是 BSTR,但是更改为任何一种数据类型都会导致相同的错误。
方法3) GetProcAddress
typedef BSTR (*Get_Data_Ptr)(BSTR Handle);
HINSTANCE LoadMe;
LoadMe = LoadLibraryA("Sensor DLL.dll");
if (!LoadMe)
std::cout << "\nDLL failed to load!\n";
Get_Data_Ptr LibMainGet_Data;
LibMainGet_Data = (Get_Data_Ptr)GetProcAddress(LoadMe,"Get_Data");
//then I call the function
LibMainGet_Data(Handle);
这将编译,但运行时会出现以下错误:
发生“System.AccessViolationException”类型的未处理异常
附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
当我在调试模式下将鼠标悬停在这段代码的各个部分时,似乎与第一种方法一样,它也无法在 DLL 中找到“Get_Data”入口点。
当您没有自己制作 DLL 并且您没有 .idl 文件等时,是否有人使用 C++ 从 VB DLL 调用函数?有没有人可以分享这样的工作示例?
谢谢!
【问题讨论】:
-
属性在 C++ 中不可用。仅在托管 C++ 中,不一样
-
您是否有意使用 C++/CLI?或者您只是因为它是调用您熟悉的 COM 对象的唯一方式而使用它?