MacOSXのdylibからVBAからCコードが呼び出されたときに、VBAから渡された文字列を変換するためのコードをCで記述しました。私はいくつかの良いヒントhereを得た、と私は唯一のASCII文字列を気にするので、私は、単純なchar*
にBSTR
を変換するには、以下の機能を書いている:CのMacOSXでのBSTRの処理
#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から呼び出されたときに機能するようです。
だから、これは動作しますが、私は理解していない一つのことは、私は2でvbstrlen
機能で私len
を乗算しなければならない理由は、私はCに新しいので、私はポインタに少し読んしなければならなかったです - BSTRには2バイトの文字が含まれているので、2倍にすることなく正しい文字列の長さを取得する必要があります。誰かが私にこのことを説明したり、チュートリアルへのリンクを投稿することができれば素晴らしいだろうか?
また、VBAで呼び出されたときの文字引数の関数は、最初の呼び出しの後でのみ機能します。だから私がBSTR*
引数を持つ関数を最初に呼び出すと(BSTR*
ポインタはちょうどいくつかの(ランダム?)アドレスを指すが文字列は指していない。私がVBAから関数を2回呼び出すと、すべてがうまくいきます。なぜこれが当てはまるのでしょうか?
このコードはコンパイルできません。ポスト*本物のコード、いぼ、そしてすべて。 –
@HansPassant 'vbstrlen'ビットは、重要ではない' #include 'をトリミングしてコンパイルしますが、dylibでコンパイルし、excel 2011 VBAから使用して、VBA文字列の戻り値0を保持します。 (with typedef wchar_t * BSTR; ') –