在 C++ 中调用 Visual Basic DLL

2021-12-25 00:00:00 dll c++

我从第三方供应商处获得了一个在 Visual Basic 中创建的 DLL (传感器 DLL.dll).这个 DLL 包含与传感器通信的函数,我需要从我正在编写的 Visual C++ 程序中调用这些函数.供应商不会提供头文件,我不知道Visual Basic.如果我有一个头文件,这将是一个 15 分钟的项目……相反,一周后我仍在努力解决它.请帮忙!

I have acquired a DLL that was created in Visual Basic from a third party vendor(Sensor DLL.dll). This DLL contains functions for talking to a sensor, and I need to call these functions from a Visual C++ program I am writing. The vendor will not provide a header file, and I do not know Visual Basic. If I had a header file this would be a 15 minute project... instead I am still struggling with it a week later. Please Help!

我听说 DLL 中的一个函数 (Get_Data) 的形式如下:

I am told one function (Get_Data) in the DLL is of the form:

Public Function Get_Data(ByVal Handle As String) As String

我尝试了几种调用这个 Get_Data 函数的方法,但都没有成功:

I have tried several methods for calling this Get_Data function with no success:

方法1) DllImport 属性

Method 1) the DllImport attribute

#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 句柄);}

[DllImport("Sensor DLL.dll", EntryPoint = "Get_Data", CharSet = System::Runtime::InteropServices::CharSet::Unicode)] BSTR Get_Data(BSTR Handle); }

//then I call the function
Sensor::Get_Data(Handle);

这种方法似乎是我最接近 slotion 的方法.编译通过,但运行时出现以下错误:

This method seems to be the closest I have gotten to a sloution. It compiles, but gives the following error when it runs:

发生类型为System.EntryPointNotFoundException"的未处理异常

An unhandled exception of type 'System.EntryPointNotFoundException' occurred

附加信息:无法在 DLL 'Sensor DLL.dll' 中找到名为 'Get_Data' 的入口点.

Additional information: Unable to find an entry point named 'Get_Data' in DLL 'Sensor DLL.dll'.

我尝试了除 BSTR 之外的各种数据类型组合/排列,包括 BSTR*、wchar_t、int 等.我可能错过了一个,但每种数据类型都返回相同的错误.

I have tried various datatype combinations/permutations besides BSTR including BSTR*, wchar_t, int, etc. It is possible that I missed one, but each datatype returns the same error.

方法二) dllimport storage-class 属性

Method 2) dllimport storage-class attribute

__declspec(dllimport) BSTR Get_Data(BSTR Handle);

//then I call the function
Get_Data(Handle);

这个方法让我很困惑,因为我没有指定要从中导入的 DLL.我已将 DLL 复制到项目文件夹中,并手动将其添加到项目中,因此希望这意味着可以找到它.当我编译链接器时返回以下错误:

This method is confusing to me because I don't specify the DLL I want to import from. I have copied the DLL to the project folder and I have added it to the project manually, so hopefully that means it can be found. When I compile the linker returns the following errors:

错误 LNK2028:未解析的令牌 (0A00034F) "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z) 在函数 "int __cdecl main(void)" (?main@@$$HYAHXZ) 中引用

error LNK2028: unresolved token (0A00034F) "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z) referenced in function "int __cdecl main(void)" (?main@@$$HYAHXZ)

错误 LNK2019:未解析的外部符号wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z) 在函数int __cdecl main(void)"中引用(?main@@$$HYAHXZ)

error LNK2019: unresolved external symbol "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z) referenced in function "int __cdecl main(void)" (?main@@$$HYAHXZ)

我怀疑这可能意味着我应该使用 wchar_t 或 wchar_t* 而不是 BSTR,但更改为任一数据类型都会导致相同的错误.

I suspected maybe this meant I should be using wchar_t or wchar_t* instead of BSTR, but changing to either datatype results in the same error.

方法 3) GetProcAddress

Method 3) GetProcAddress

typedef BSTR (*Get_Data_Ptr)(BSTR Handle);  
HINSTANCE LoadMe;
LoadMe = LoadLibraryA("Sensor DLL.dll");

if (!LoadMe)
    std::cout << "
DLL failed to load!
";

Get_Data_Ptr LibMainGet_Data;  
LibMainGet_Data = (Get_Data_Ptr)GetProcAddress(LoadMe,"Get_Data");

//then I call the function
LibMainGet_Data(Handle);

这会编译,但运行时会出现以下错误:

This will compile, but gives the following error when run:

发生类型为System.AccessViolationException"的未处理异常

An unhandled exception of type 'System.AccessViolationException' occurred

附加信息:尝试读取或写入受保护的内存.这通常表明其他内存已损坏.

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

当我在调试模式下将鼠标悬停在此代码的各个部分上时,似乎与第一种方法一样,它也无法在 DLL 中找到Get_Data"入口点.

When I mouse over the various parts of this code in debug mode it seems that, like the first method, it was also unable to find the 'Get_Data' entry point in the DLL.

当您没有自己制作 DLL 并且没有 .idl 文件等时,是否有人使用 C++ 从 VB DLL 调用函数?有没有人可以分享这样的工作示例?
谢谢!

Has anyone called functions from a VB DLL using C++ when you haven't made the DLL yourself and you don't have .idl files, etc? Does anyone have a working example like this you could share?
Thanks!

推荐答案

VB6 DLL 通常是 COM 服务器.实际上,您确实有一个等效的 .h 文件,其中嵌入了一个类型库.从 Project + Properties、Common Properties、Framework 和 References 开始.添加新引用按钮,浏览选项卡,选择 DLL.

A VB6 DLL is normally a COM server. You do in fact have the equivalent of a .h file, it has a type library embedded in it. Start this off with Project + Properties, Common Properties, Framework and References. Add New Reference button, Browse tab, select the DLL.

接下来,查看 + 对象浏览器.您应该会在列表中看到生成的 Interop 库.打开节点看看有什么.您可以编写普通的托管代码(如 gcnew)来创建 COM 对象并调用接口方法.您确实需要一些关于可用方法的最低限度的文档来猜测它们应该如何被调用.

Next, View + Object Browser. You should see the generated Interop library in the list. Open the node to see what is there. You write normal managed code, like gcnew, to create the COM object and call the interface methods. You do need some minimum documentation on the available methods to have a guess at how they should be called.

相关文章