导出c++;函数,在vb6中声明,获取;“远程过程调用失败”;运行时错误 我有一个用C++编写的DLL,它是这样输出的: extern "C" { extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat); }

导出c++;函数,在vb6中声明,获取;“远程过程调用失败”;运行时错误 我有一个用C++编写的DLL,它是这样输出的: extern "C" { extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat); },vb6,windows-server-2003,managed-c++,Vb6,Windows Server 2003,Managed C++,该功能在其他地方定义为: extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat) { Tools::Merge(gcnew String(szFileName), gcnew String(szMergeString), dwAlignment, fRepeat == TRUE); } 在我的vb6 dll中

该功能在其他地方定义为:

extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat)
{   
    Tools::Merge(gcnew String(szFileName), gcnew String(szMergeString), dwAlignment, fRepeat == TRUE);
}
在我的vb6 dll中,我声明了如下远程调用:

Private Declare Sub Merge Lib "Tools.dll" (fileName As String, mergeString As String, Alignment As Long, repeated As Boolean)
Merge strPageFileName, "COPY", 5, True
然后我在代码中这样调用它:

Private Declare Sub Merge Lib "Tools.dll" (fileName As String, mergeString As String, Alignment As Long, repeated As Boolean)
Merge strPageFileName, "COPY", 5, True
当我运行应用程序时,我会在一个消息框中看到“自动化错误:远程过程调用失败”

Tools.dll
位于C:\Windows\system32中。我测试了一个坏的dll名称,以确保这不是问题,并得到一个错误,说它无法找到该文件,所以我知道这不是它。我还需要做些什么才能让它工作

编辑:根据下面xxbbcc的答案更改变量类型,使其能够正确运行。然而,它创造了一个新的,到目前为止完全无法解决的问题。我提出了另一个问题,其中有一些细节

远程调用发生在COM+dll中,在一个函数内,该函数将类型
integer
返回给另一个非COM dll。出于某种奇怪的原因,COM+dll函数现在返回类型为
VT_ERROR
的变量,而不是整数。我已经对此进行了彻底的测试,并确定无论我事先如何处理返回值,将其设置为任何值,等等,它都会返回一个错误。奇怪的是,错误值显然是0。我调用了
CInt(returnValue)
CStr(returnValue)
,和
CLng(returnValue)
,它们分别返回
0
错误0
,和
0


我一直找不到任何信息来解释为什么一个本来应该返回整数的函数会突然返回一个错误。这给了我一个非COM+函数中的类型不匹配错误,因为它试图将返回赋值给一个局部整数。将其更改为变体可以让我进行上述转换。调用
VarType(returnValue)
得到10,即
vbError
。我们不希望从COM+dll中的其他调用中丢失失败信息,因此我不能忽略返回值。

尝试在VB6 Declare语句中用VAL声明字符串参数。将“文件名为字符串”改为“BYVAL文件名为字符串”等。

< P>我目前的解决方案是编写一个调用输出函数的小型C++控制台应用程序,并从vb6 dll中调用exe。

BOOL
应在vb6中定义为
Long
,为其传递的值应为
0
1
,而不是布尔值。它也应该是<代码> ByVal < /C> >因为参数在C/C++中通过,必须确保VB6程序遵循该规则。现在,VB6程序将指针传递给
布尔值
,而不是实际的
长值
。字符串还应定义为
ByVal

虽然有日期,但它提供了一些有用的信息,说明为什么字符串应该作为
ByVal
从VB6传递到C代码


另一件事-我从未使用declspec(dllexport)成功地将函数导出到VB6。我以前做过很多C/VB6编码,但唯一有效的方法是通过DEF文件。我无法解释原因(可能是因为我的无知)。如果修复BOOL参数可以解决您的问题,请忽略我答案的这一部分。:)

不走运。谢谢你的建议。你是否试过运行
dumpbin/exports
来验证你导出的函数的名称是否与你的VB6客户端对它的要求完全一致?(即,DLL中函数名完全未被修改)?另一个要检查的事情:C++函数实际上是调用的吗?如果在其中放置断点,是否命中?是的,正如您所期望的那样,它正在显示函数
Merge
。调试的问题是,它位于服务器上,没有方便的方法在服务器上调试或在我的PC上测试。我尝试过另一种方法,使用regasm并将其作为COM dll运行,这样会出现错误438,表示找不到函数。只是验证一下:您是否使用了
regasm
regsvr32
?如果这是一个普通的C/C++DLL,regasm将不会做任何事情。另外,如果没有类型库,您不能将普通函数导出到COM-您的DLL有类型库吗?(您可以通过这种方式将全局函数导出到VB6,但是需要类型库。)是的,我经常使用这种方法。当我运行regasm时,我让它创建类型库。在这种情况下,它似乎为一个enum类创建了正确的注册表项,该类只有一组用于对齐的值,但它没有使用merge函数为另一个类创建一个项。我可以看到vb6中显示的对齐值,但不能看到函数。当我将类暗显为对象,然后将其设置为工具类时,它无法生成。在VB6中,您无法看到.NET类的静态函数-我不相信类型库创建者会为此创建模块条目。您可以尝试在VB6中查找
工具。合并
,但我怀疑它是否存在(从未尝试过)。对于全局
Merge
函数,使用DEF文件导出它,然后VB6应该能够调用它。您仍然需要根据我的回答修复您的
声明
语句。现在你试图用错误的参数调用你的函数。这似乎已经解决了问题,因为文件现在已经正确合并了,但是我在这段代码之后遇到了一个类型不匹配错误,这会导致应用程序失败并且无法完成,所以我正在尝试解决这个问题。一旦问题解决了,我会接受这个答案。谢谢@JoeMajsterski谢谢你,如果你有更多问题,请告诉我。很高兴听到你的问题解决了。