我使用Code::块来用C编写DLL,我打算在Win批处理脚本中使用它,但目前我正在使用Excel测试它。当VBA脚本运行DLL getVersion()函数Excel时崩溃。在网上搜索了几天:我没有找到合适的解决方案。
C代码是这样的
#define MQTTPUB_VERSION "V3.1.1Test"
DLL_EXPORT BSTR __stdcall WINAPI getVersion(void)
{
return MQTTPUB_VERSION ;
}VBA代码如下所示
Public Declare Function mqttPubMsg Lib "mqttPubMsg.dll" _
(ByVal MQTT_ADDRESS As String, ByVal MQTT_CLIENTID As String, ByVal MQTT_TOPIC As String, ByVal MQTT_PAYLOAD As String) As Long
Public Declare Function getVersion Lib "mqttPubMsg.dll" () As String
Sub Test_DDL_mqttPubMsg()
'
' to test mqttPubMsg.DLL used in Visual Basic (VBA)
'
Dim DLLVersion As String * 35
Dim WorkDir As String
DLLVersion = Space(35)
WorkDir = ThisWorkbook.Path
ChDir WorkDir
If Dir(WorkDir & "\mqttPubMsg.dll", vbDirectory) = vbNullString Then
MsgBox "DLL not found"
Else
On Error GoTo DLLError
DLLVersion = getVersion() 'Excel crashes on executing this statement
End If
MsgBox ("Version DDL: " & DLLVersion)
Exit Sub
DLLError:
MsgBox ("DDL error")
End Sub调用DLL和getVersion()函数的C程序工作正常。
导致此运行时错误的原因是什么以及如何解决它。
提前谢谢。
发布于 2016-03-16 16:20:14
我最近还没有进行Windows编程,也没有现成的开发环境可供实验,但以下是一些想法。
这里最可能的问题是getVersion()返回BSTR,当返回类型被声明为String时,调用VBA代码也(可能)期望返回。现在,BSTR应该在内存中的前面加上一个4字节的长度前缀,参见https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069%28v=vs.85%29.aspx。getVersion()只返回一个指向"V“的指针,这是字符串的第一个字符,当VBA试图将前面的4个字节解释为"V”之前的长度时,这是一个灾难.
以下是我看到的一些可能的解决方案:
BSTR中的SysAllocString()函数构造getVersion()。DLLVersion字符串传递给getVersion(),并查看是否可以在getVersion()中填充它。请记住,您在这里处理Unicode。出于好奇,还有几件事情要玩儿:
getVersion()返回void,并查看调用该函数是否会使Excel崩溃。如果是的话,那么问题就更深了。getVersion()返回一个整数,看看是否可以在您的VBA代码中得到它。getVersion()将一个整数作为参数,从VBA传递一个整数,并查看C代码是否能够得到正确的值。getVersion()返回指向buf + 4的指针,其中buf是全局char数组。对不起,我的记忆不是新鲜的,我不能提供更具体的建议,但希望这能有所帮助。
https://stackoverflow.com/questions/36018442
复制相似问题