0

我有一个用 C++ 编写的 dll,正在像这样导出:

extern "C" {
    extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat);
}

该函数在其他地方定义为:

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

当我运行该应用程序时,我在消息框中收到“自动化错误:远程过程调用失败”。

Tools.dll位于 C:\Windows\system32 中。我用一个错误的 dll 名称进行了测试,以确保这不是问题,并得到一个错误,说它找不到文件,所以我知道不是它。我还需要做什么才能使其正常工作?

编辑:根据下面的 xxbbcc 的答案更改变量类型允许它正常运行。然而,它创造了一个新的、迄今为止完全无法解决的问题。我在这里创建了另一个问题,其中包含一些有关它的详细信息。

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

我一直找不到任何信息来解释为什么应该返回整数的函数会突然返回错误。这给了我非 COM+ 函数中的类型不匹配错误,因为它试图将返回分配给本地整数。将其更改为变体允许我进行上述转换。呼叫VarType(returnValue)给出 10,即vbError。我们不想潜在地丢失 COM+ dll 中其他调用的失败信息,所以我不能忽略返回值。

4

3 回答 3

1

BOOL应该像Long在 VB6 中那样定义,并且为它传递的值应该是0or 1,而不是布尔值。它也应该是ByVal- 因为参数是通过 C / C++ 中的值传递的,所以您必须确保您的 VB6 程序遵循这一点。现在您的 VB6 程序传递一个指向 a 的指针Boolean,而不是一个实际的Long. 您的字符串也应该定义为ByVal.

这篇文章——虽然过时了——有一些关于为什么字符串应该从 VB6 传递ByVal到 C 代码的有用信息。

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

于 2013-05-11T03:02:04.550 回答
0

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

于 2013-05-07T21:59:36.573 回答
0

我目前对此的解决方案是编写一个调用导出函数的微型 c++ 控制台应用程序,并从 vb6 dll 中调用 exe。

于 2013-05-09T18:11:24.290 回答