在C++项目中调用VB生成的DLL:可行性与实现方法
VB生成的DLL在C++中调用的可行性与实现方案
可行性说明
可以实现,但VB默认生成的是COM组件(ActiveX DLL),不是C常用的「标准导出函数DLL」,直接用LoadLibrary+GetProcAddress调用会失败——两者的导出机制完全不同。如果是VB中特意配置导出的标准函数DLL,才可以用类似C DLL的方式调用,但这种情况较少见。
两种常见实现方案
方案1:调用VB生成的COM DLL(最常用)
VB编写的DLL绝大多数是COM组件,需要通过COM接口调用,步骤如下:
- 注册VB DLL:打开管理员权限的命令提示符,执行
regsvr32 "你的VB DLL完整路径",完成组件注册;
- 注册VB DLL:打开管理员权限的命令提示符,执行
- 在C++中引用COM类型库:
- 用
#import "你的VB DLL路径"让编译器自动生成包装类,简化调用; - 或手动操作COM:调用
CoInitialize初始化COM库,CoCreateInstance创建对象实例,再调用接口方法;
- 调用示例(以
#import为例):
- 调用示例(以
#include <comdef.h> // no_namespace表示不使用命名空间,可根据VB DLL的实际情况调整 #import "C:/Users/Downloads/Vb/Vb-DLL/bin/Debug/Mydll.dll" no_namespace int main() { // 初始化COM环境 CoInitialize(NULL); try { // IMotorControlPtr是编译器自动生成的智能指针,对应VB DLL中的接口 // MotorControl是VB项目中定义的类名,需替换为实际名称 IMotorControlPtr pMotor; pMotor.CreateInstance(__uuidof(MotorControl)); // 调用VB中定义的GetMotor1Position方法 short pos = pMotor->GetMotor1Position(); // 处理获取到的结果 } catch (_com_error& e) { // 捕获并处理COM调用错误 } // 释放COM资源 CoUninitialize(); return 0; }
方案2:调用VB导出的标准函数DLL(需VB特殊配置)
如果你的VB项目是特意导出标准函数的(比如VB6中用Attribute标记导出,VB.NET中用<DllExport>属性),可以调整C++调用方式,重点解决以下问题:
- VB导出的函数名通常带有装饰后缀(比如
_GetMotor1Position@0),需要用dumpbin /exports Mydll.dll命令查看实际导出的函数名; - 修正你代码中的错误:
你当前代码的问题:
- 函数名不匹配:typedef定义的是
GetMotor1Position,但GetProcAddress查找的是"GetMotor1Speed"; - 调用方式错误:应该用
MotorPosPtr()调用函数指针,而非直接调用GetMotor1Position(); - 字符集问题:
LoadLibrary(_T(...))对应GetProcAddress应该用TEXT("函数名")统一字符集; - 未获取到正确的导出函数名:VB导出的函数名大概率有装饰,需用
dumpbin工具确认。
修正后的示例代码:
#include <windows.h> #include <iostream> // 函数指针类型定义,需与VB中函数的参数、返回值一致 typedef short (CALLBACK* GetMotor1Position)(); int main(int argc, char *argv[]) { BOOL freeResult = FALSE; GetMotor1Position MotorPosPtr = NULL; HINSTANCE hGetProcIDDLL = LoadLibrary(_T("C:/Users/Downloads/Vb/Vb-DLL/bin/Debug/Mydll.dll")); if (hGetProcIDDLL == NULL) { std::cout << "Library Mydll.dll not found" << std::endl; return 1; } // 替换为dumpbin查到的实际导出函数名,示例为"_GetMotor1Position@0" MotorPosPtr = (GetMotor1Position)GetProcAddress(hGetProcIDDLL, "_GetMotor1Position@0"); if (MotorPosPtr != NULL) { short a = MotorPosPtr(); // 通过函数指针调用VB导出的函数 std::cout << "Motor position: " << a << std::endl; } else { std::cout << "Failed to get function address" << std::endl; } freeResult = FreeLibrary(hGetProcIDDLL); return 0; }
关键提示
- 优先选择COM方案:VB天生适合开发COM组件,这种调用方式更稳定,也符合VB DLL的设计初衷;
- 确认导出函数:用Visual Studio自带的
dumpbin /exports 你的DLL路径工具,检查DLL是否导出了标准函数及具体名称; - 权限注意:注册COM DLL需要管理员权限,否则会注册失败。
内容的提问来源于stack exchange,提问作者Soukaina
相关产品推荐
相关产品推荐

