当从 MacOSX dylib 从 VBA 调用 C 代码时,我用 C 编写了一些代码来转换从 VBA 传递的字符串。我在这里得到了一些很好的提示,因为我只关心 ASCII 字符串,所以我编写了以下函数来将其转换BSTR
为简单的char*
:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "myheader.h"
size_t vbstrlen(BSTR *vbstr)
{
size_t len = 0U;
while(*(vbstr++)) ++len;
len = len*2;
return len;
}
void vbstochr(BSTR *vbstr, char** out)
{
int len2 = vbstrlen(vbstr);
char str[len+1];
int i;
for(i = 0; i < len; i++)
{
str[i] = (char) (((uint16_t*) vbstr)[i]);
}
str[i] = '\0';
asprintf(out, str);
}
int test(BSTR *arg1)
{
char* convarg;
vbstochr(arg1, &convarg);
return 1;
}
myheader.h 看起来像这样:
typedef uint16_t OLECHAR;
typedef OLECHAR * BSTR;
. 我使用uint16_t
MacOSX C 编译器中的 4 字节(不是 2 字节)wchar_t。我在调用后添加了一个断点vbstochar
来查看 的内容convarg
,从 Excel 调用它似乎可以工作。
所以这行得通,但我不明白的一件事是为什么我必须将函数len
中的我乘以vbstrlen
2。我是 C 的新手,所以我不得不稍微阅读一下指针 - 我想自从我的 BSTR包含 2 个字节的字符,我应该得到正确的字符串长度而不必乘以 2?如果有人可以向我解释这一点,或者发布指向教程的链接,那就太好了?
此外,我的带有字符串参数的函数在 VBA 中调用时有效,但仅在第一次调用之后。因此,当我BSTR*
第一次使用来自 dylib 的参数调用函数时(在我启动应用程序后,在本例中为 Excel),BSTR*
指针只指向某个(随机?)地址,而不是字符串。当我第二次从 VBA 调用该函数时,一切正常 - 任何想法为什么会这样?!