2017-07-14 5 views
0

私はC DLLを持っています。私はPInvokingしています。主な目的は、abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdなど、39文字のGUID文字列を取得することです。ユニットテストでStringBuilderを使用してPInvokingする

私が最初に私が39個の文字であることを期待され、この文字列のサイズを取得するには1つのメソッドを呼び出して、そして私は39の容量を持つStringBuilderを渡し、別の関数を呼び出す:

[DllImport("test.dll")] 
public static extern int get_size(); 

[DllImport("test.dll")] 
public static extern void get_string(StringBuilder result); 

私のコードabcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd

:私は、コンソールアプリケーションでこれを呼び出すと、私は戻って、この結果を得る

int size = get_size(); // Returns 40, because it includes the null terminating character. 
var result = new StringBuilder(size - 1); // Gives it a capacity of 39. Subtracting 1 here because this does not fancy that null terminator over the marshaling layer. 
get_string(result); 
Console.WriteLine(result.ToString()); 

:次のようになります10正確に同じコードで単体テストから呼び出すと、私はこの結果を返します。abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdq

最後にqが追加されていることと、追加される余分な文字と、私が確認できる単体テストをデバッグしたことに注意してくださいStringBuilderオブジェクトの容量が、の後に42 まで大幅に増加したことを示します。容量が39で初期化されていますが、get_stringへの呼び出しが行われました。これは正常ですか?私は何か間違っているのですか?なぜ単体テストでしかないのですか?

Cの実装では、このようなものである:これは、いくつかの修正が必要な

static char *_result = NULL; // At some point result is initialized and set. 

int get_size() { 
    if (_result != NULL) 
     return strlen(_result) + 1; 
    return 1; 
} 

void get_string(char *result) { 
    if (result != NULL && _result != NULL) 
     strncpy(result, _result, strlen(_result)); 
} 
+0

おそらく、これらの関数のC実装は、いくつかの光を放つかもしれません。あなたはそれを追加できますか? –

+0

@FelixPalmenある瞬間、私はそれを追加します。 – Alexandru

+0

その質問に対する答えは分かりませんが、サイズを一切与えなかったのですか? – jambodev

答えて

1

変更するために必要な関数シグネチャ:変更する必要

[DllImport("test.dll")] 
public static extern int get_size(); 

[DllImport("test.dll")] 
public static extern void get_string(int resultSize, StringBuilder result); 

Cの実装:

static char *_result = NULL; // At some point result is initialized and set. 

int get_size() { 
    if (_result != NULL) 
     return strlen(_result) + 1; 
    return 1; 
} 

void get_string(int resultSize, char *result) { 
    memset(result, 0, resultSize); 
    if (_result != NULL) 
     strncpy(result, _result, resultSize); 
} 

変更するために必要なC#のコール:

int resultSize = get_size(); 
var result = new StringBuilder(resultSize); // Needed to also include the null Terminator ("I'LL BE BACK" - ARNOLD). 
get_string(resultSize, result); 
Console.WriteLine(result.ToString()); 

音符新人にCの... charを使用していない場合は、012のようなものを使用していますなど、文字列の長さの計算方法に加えて、memsetのような操作を行う場合は、代わりにsizeof(wchar_t)というバッファサイズを掛ける必要があります。文字列の文字数と文字列のバイト数には大きな違いがあるためです。私はちょうどsizeof(char)が1であることを知っているので、コードを保存する実装からこれを省略しました。

関連する問題