Я написал код в C для преобразования строк, переданных из VBA, когда код C вызывается из VBA из MacOSX dylib. Я получил несколько хороших советов here, и так как я забочусь только о ASCII строки я написал следующие функции преобразующие BSTR
к простому char*
:Обработка BSTR на MacOSX в C
#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
из-за 4 байтов (не 2 байта) wchar_t в компиляторе MacOSX C. Я добавил точку останова после вызова vbstochar
, чтобы посмотреть содержимое convarg
и, похоже, работает при вызове из Excel.
Так что это работает, но я не понимаю, почему я должен умножить свой len
в функции vbstrlen
на 2. Я новичок в C, поэтому мне пришлось немного почитать указатели - и я думал, так как мой BSTR содержит 2 байтовых символа, я должен получить нужную длину строки без необходимости умножать на два? Было бы здорово, если бы кто-нибудь мог объяснить это мне или опубликовать ссылку на учебник?
Кроме того, мои функции со строковыми аргументами работают при вызове в VBA, но только после первого вызова. Поэтому, когда я вызываю функцию с аргументом BSTR*
из dylib в первый раз (после запуска приложения, Excel в этом случае), указатель BSTR*
просто указывает на какой-то (случайный?) Адрес, но не на строку. Когда я вызываю функцию из VBA во второй раз, все работает отлично - любые идеи, почему это так?
Этот код не может скомпилировать. Сообщение * реальный * код, бородавки и все. –
@HansPassant бит 'vbstrlen', с обрезкой неживого' # include''s, компилируется, но компилируется в dylib и используется с excel 2011 VBA, возвращает 0 для любой строки VBA. (С 'typedef wchar_t * BSTR;'.) –