2017-06-19 27 views
-1

質問と同じです。私はいくつかのVBAコードで文字列の配列を作ることができるようにしたい、このコードでは、それらを特定の長さにしたいと思います。次に、それらをC++ DLLにどのように渡すか、DLL内で各要素に文字列を格納し、これらの要素を後でVBAからアクセス可能にしたいと考えています。私はすでに1つの文字列に対して、そして2つの配列に対して以下のようにしています。VBA/Excelで文字列の配列を作成し、DLLでそれを繰り返し処理できるようにC++ DLLに送信する方法

Dim myStr As String * sizeConst 

Dim dataArray() As Double 
ReDim dataArray(0 To (arrayLength - 1)) As Double 

次に、それらをVBA内からDLLに渡します。

Public Declare Function myFunc _ 
Lib "PathToDLL.dll" _ 
(myStr As String, ByVal sizeConst As Integer, dataArray As Double, ByVal arrayLength As Long) As Long 

そしてDLLに私は二重配列の各要素をステップすることができます。しかし、私は文字列の配列のためにこれを行う方法を知らない。私は、VBAから渡される文字列の実際のメモリサイズがsizeConst + 1のサイズであるかどうか不安です。私は次の文字列要素に到達するためにどれだけ増やすべきかを知るためにこれを知る必要があります。誰かが、各要素の長さを一定にしてVBAで文字列配列を宣言する方法を教えてもらえますか?次に、その配列をDLLに渡す方法と、DLLの文字列配列の次の要素にインクリメントする方法。あなたはDeclare D機能でarr() as stringを宣言する場合

+0

私の答えをダウン投票していただきありがとうございます。「固定サイズの文字列の配列を作成する方法」という質問に対する回答が条件に合わない場合は、より具体的で問題の適切な詳細を提示する必要があります。 –

+0

@MaciejLos重要な部分は「次にC++ DLLにどのように渡すか」です。詳細については、https://stackoverflow.com/questions/44396538/vba-excel-and-c-dll-specifically-problems-with-strings#comment76262029_44396538を参照してください。 – GSerg

+0

@GSerg、これは疑問の第二の部分です。私はこの情報を提供しました: 'あなたのdllは、関数宣言のために、文字列の配列ではなく、** myStr As String **と入力することを期待しています。トリックは質問をするスキルです! –

答えて

1

、VBはBSTR S(FADF_BSTR | FADF_HAVEVARTYPE)からなるLPSAFEARRAY*(ダブルポインタ、SAFEARRAY**)を送信します。つまり、conversion to LPSTRは実行されません。

C++側では、パラメータをLPSAFEARRAY*と宣言し、SafeArray* family of functionsを使用してデータを操作します。

交換する場合は、交換する予定のBSTRを解放する責任があります。

LPSAFEARRAYから配列のサイズとサイズに関するすべての情報を取得し、それぞれBSTRは文字列の長さを格納します。


あなたがarr() as string * some_lengthを宣言するときも同様ですが、今回はSAFEARRAYは唯一FADF_HAVEVARTYPEのものであろう、とSafeArrayGetVartypeVT_ERRORを返します。安全な配列の各要素は、ゼロターミネータまたは文字列の長さが別々に格納されていない、some_lengthワイド文字(some_length * 2バイト)の事前割り当てブロブになります。おそらくそれはあらかじめ割り当てられているため、各要素の既存のメモリを単純に満たすことができるので、作業するのがさらに簡単です。


あなたは固定長せず、単なる文字列を使用した場合、あなたはまた、あなたが倍増するポインタを渡しているのと同じ方法でそれらを渡すことができますCに続いて

declare function myFunc ... (byval strings as longptr, byval count as long) 
dim s() as string 
redim s(1 to 5) 

myFunc varptr(s(lbound(s))), ubound(s) - lbound(s) + 1 

++あなたは最初の文字列のBSTR*を受け取り、次の文字列に進むには、普通はポインタの計算と同様に1を追加します。いくつの文字列があるかを知るためには、要素数を別のパラメータとして渡す必要があります。

これは固定長文字列では機能しません。

+0

ありがとうGSerg。私は単純に非固定長の例を使用すると思います。最初のBSTRへのポインタではなく、C++側の型がLPWSTRになるのは、他のBSTR要素(サイズを格納するメモリ)からの余分なメモリがないからです。 –

+0

私はもう一度ストレスを感じています。以前の投稿とこの記事も私があなたに提供してくれたことに感謝しています。 –

+0

@AlexWardlow私はそれを 'LPWSTR'と呼ぶのに慣れています。なぜなら、これはC++側でほとんどの場合起こるからです。はい、ポインタは 'BSTR * 'になります。これは 'BSTR'がどのように設計されているのか、文字列データ(文字列ポインタとは対照的に)が次々とメモリの連続ブロックに格納されないために、何かをかわす必要はありません。 – GSerg

関連する問題