我有一个我用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/Interfacing_Visual_Basic_And_C.shtml
答案 0 :(得分:4)
通过使用__declspec
进行导出,函数名称将被导出 mangled ,即包含类型信息以帮助C ++编译器解决重载问题。
VB6无法处理损坏的名称。作为一种解决方法,您必须对名称进行去除。最简单的解决方案是使用VC ++中的export definition文件链接DLL文件。导出定义文件非常简单,只包含DLL的名称和导出函数列表:
LIBRARY mylibname
EXPORTS
myfirstfunction
secondfunction
此外,您必须指定stdcall
调用约定,因为这是VB6可以处理的唯一调用约定。有一个项目使用程序集注入来处理C调用,但我想你不想使用这种困难且容易出错的方法。
答案 1 :(得分:3)
尝试在最后添加__stdcall
#define MYDCC_API __declspec(dllexport) __stdcall
我们有一些与我们的旧VB6应用程序交互的C ++ dll,最后他们都有这个。
答案 2 :(得分:0)
VB6 DLL始终是COM dll。我将用尽可能少的单词描述一个例子。假设你在VB6中有一个ActiveX DLL项目,它有一个名为CTest的类,它包含一个如下所示的方法
公共函数vbConcat(ByVal a As String,ByVal b As String)As String 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;
void 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);
}
}
这就是它的全部,开始时。