【问题标题】:Unable to pass a string from vba to a windows dll无法将字符串从 vba 传递到 windows dll
【发布时间】:2017-04-18 18:17:44
【问题描述】:

我有 64 位 Windows 10 和 MS Office 64 位。我正在尝试让 PowerPoint 的 VBA 加载并执行自写的 64 位 Windows DLL 中的函数。

问题是我无法将字符串从 VBA 传递到 Windows DLL。在各种网站上有很多讨论,但我没有找到一个有效的。 我尝试了两种方法都没有成功。如果我使用调用 DLL 的 C++ 应用程序,我没有问题。

方法一:

DLL:

extern "C" {
    __declspec(dllexport) long jaadd(long a, long b, LPCWSTR strg)
    {
    MessageBoxW(NULL, strg, L"DLL", MB_OK);
    return a+b;
    }
}

在 VBA 中:

Private Declare PtrSafe Function jaadd Lib "D:\\Visual Studio 2017\\Projects\\PopUpDLL\\x64\\Debug\\PopUpDLL.dll" _
             (ByVal arg1 As Long, ByVal arg2 As Long, ByVal lParam As String) As Long
y = jaadd(1, 2, "abcdxxxxx")

结果: y = 3 这是正确的,但消息框显示象形文字。

方法 2 - 不使用宽字符串:

DLL:

extern "C" {
    __declspec(dllexport) long jaadd(long a, long b, LPCSTR strg)
    {
        MessageBoxA(NULL, strg, "DLL", MB_OK);
        return a+b;
    }
}

VBA 是一样的

结果: y = 3 这是正确的,但消息框显示“无”。

收到任何帮助。

【问题讨论】:

  • VBA 中的字符串是BSTR。可能是空终止符搞砸了。
  • @Mat'sMug: BSTR's 以零结尾,就像任何其他 C 风格的字符串一样。指针还指向第一个字符(不是长度前缀)。即使LPCWSTR 是错误的类型,它仍然可以安全地用作参数,如果它通过BSTR。 @JonAnthony:你能发布通过strg 传递的缓冲区的内容吗(开始比指针低4 个字节)?
  • 不确定这在 VBA 中是否合法,但您可能必须具体说明编组,即 <MarshalAs(UnmanagedType.LPWStr)> lParam As String
  • @Mat'sMug:MarshalAs 属性是 P/Invoke 声明的一部分,与 C# 中的相同。 VBA 也不需要知道LPCWSTR 是什么。如果它通过了BSTR,C++ 代码应该没问题,即使它没有严格使用正确的类型。
  • @Mat'sMug:微软的 C++ 编译器也使用 32 位宽的 longs(参见 data type ranges),所以没有直接的额外问题(添加 n 位数字并将结果存储在无论如何,一个 n 位数字在 50% 的所有可能情况下都会溢出)。至于字符串类型:如果 VBA 实际上传递了BSTR,则库不需要转换任何内容。 BSTR 已经一个有效的LPCWSTR。所以要么 VBA 没有通过BSTRs,要么封送器做了我不知道的事情。

标签: string windows vba dll parameters


【解决方案1】:

感谢您的所有帮助。这与 VBA 处理字符串的方式有关。我似乎已经解决了这个问题。如果我有:

__declspec(dllexport) long jastr(long a, LPCWSTR strg)

然后在 VBA 中我有

Private Declare PtrSafe Function jastr Lib "<DLL Path>" _
(ByVal arg1 As Long, ByVal arg2 As LongPtr) As Long

我有

Dim strVar As String, ptrVar As LongPtr, y As Long
strVar = "hellothere"
ptrVar = StrPtr(strVar) ***create a pointer to start of string,ie at the 5th byte
y = jastr(40, ptrVar)

DLL 中的消息框输出 hellothere 并且 y 是正确的。 我确实推荐以下链接,这对我有很大帮助:

http://bytecomb.com/vba-internals-string-variables-and-pointers-in-depth

但我仍然遇到三个或更多长参数的 jaadd 问题。

【讨论】:

    猜你喜欢
    • 2014-02-24
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多