从VB6调用DLL函数
我有一个用C / C ++编写的Windows DLL(所有导出的函数均为" C")。该DLL在VC ++中对我来说工作正常。我已经将DLL交给了另一家在VB中进行所有开发的公司。他们似乎在链接到功能时遇到问题。我已经十年没有使用VB了,甚至没有安装它。可能是什么问题呢?
我已经声明了我所有的公共职能,如下所示:
#define MYDCC_API __declspec(dllexport) MYDCCL_API unsigned long MYDCC_GetVer( void); . . .
有任何想法吗?
终于回到今天,并使其正常工作。答案使我走上了正确的道路,但我发现这最有帮助:
http://www.codeproject.com/KB/DLL/XDllPt2.aspx
另外,在将字符串传递给DLL函数时遇到了一些问题,我发现这很有帮助:
http://www.flipcode.com/archives/Interinterface_Visual_Basic_And_C.shtml
解决方案
回答
通过使用__declspec进行导出,函数名称将被导出,其中包含类型信息以帮助C ++编译器解决重载。
VB6无法处理变形的名称。解决方法是,必须取消名称的组合。最简单的解决方案是使用VC ++中的导出定义文件链接DLL文件。导出定义文件非常简单,仅包含DLL的名称和导出函数的列表:
LIBRARY mylibname EXPORTS myfirstfunction secondfunction
另外,我们必须指定stdcall
调用约定,因为这是VB6可以处理的唯一调用约定。有一个项目使用程序集注入来处理C调用,但是我想我们不想使用这种困难且容易出错的方法。
回答
尝试在末尾添加__stdcall
#define MYDCC_API __declspec(dllexport) __stdcall
我们有一些与旧的VB6应用程序交互的C ++ dll,它们都在末尾具有该功能。
回答
VB6 DLL始终是COM dll。我将用尽可能少的词来描述一个例子。假设我们在VB6中有一个ActiveX DLL项目,其类名为CTest,其中包含如下所示的方法
公共函数vbConcat(ByVal a作为字符串,ByVal b作为字符串)作为字符串
vbConcat = a和b
结束功能
并且我们已经在VB6项目属性中将项目名称设置为VBTestLib,并且
我们已将项目编译为F:\ proj \ VB6 \ ActiveXDLL \ VBTestDLL.dll
我们需要使用Windows命令注册dll
regsvr32 F:\ proj \ VB6 \ ActiveXDLL \ VBTestDLL.dll
现在C ++代码:
#import" F:\ proj \ VB6 \ ActiveXDLL \ VBTestDLL.dll"
使用命名空间VBTestLib;
无效的CDialogTestDlg :: OnButton1()
{
HRESULT hresult; CLSID clsid; _CTest *t; // a pointer to the CTest object _bstr_t bstrA = L"hello"; _bstr_t bstrB = L" world"; _bstr_t bstrR; ::CoInitialize(NULL); hresult=CLSIDFromProgID(OLESTR("VBTestLib.CTest"), &clsid); hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER, __uuidof(_CTest),(LPVOID*) &t); if(hresult == S_OK) { bstrR = t->vbConcat(bstrA , bstrB); AfxMessageBox((char*)bstrR); }
}
这就是开始的全部内容。