2017-03-21 3 views
1

私はCで別のクラスの一部として書かれた以下の機能を持っている:この文字配列パラメータをCからC#の文字列にマーシャリングするにはどうすればよいですか?

int example(char *remoteServerName) 
{ 
    if (doSomething(job)) 
     return getError(job); 
    if (job->server != NULL) { 
     int length = strlen(jobPtr->server->name); // name is a char * of length 1025 
     remoteServerName = malloc (length * sizeof(char)); 
     strncpy(remoteServerName, jobPtr->server->name, length); 
    } 
    return 0; 
} 

は、どのように私は戻ってそれからremoteServerNameを得ることができますか?私は以下を試しました:

[DllImport("example.dll")] 
public static extern int example(StringBuilder remoteServerName); 

var x = new StringBuilder(); 
example(x); 
Console.WriteLine(x.ToString()); 

しかし、文字列は常に空です。 。あなたがで返される文字列のためにいくつかのスペースを割り当てる必要が代わりの

+0

Cはクラスをサポートしていません。 – Olaf

答えて

4

var x = new StringBuilder(); 

は、容量値を提供します。

var x = new StringBuilder(1024); 

あなたはまた、mallocにお電話を削除する必要があります。呼び出し元はメモリを割り当てます。それはStringBuilderでマーシャリングの目的です。

strncpyは正しく使用されていないため、ヌルターミネータを書き込むことはできません。

int example(char *remoteServerName) 
{ 
    if (doSomething(job)) 
     return getError(job); 
    if (job->server != NULL) { 
     // note that new StringBuilder(N) means a buffer of length N+1 is marshaled 
     strncpy(remoteServerName, jobPtr->server->name, 1025); 
    } 
    return 0; 
} 

をしかし、それは暗黙的に指定され、すべてのゼロ詰めで、少し無駄になります:あなたはこのようにバッファ長を渡すことができます。実際には、strncpyは無用の隣にあり、ここで何度も議論されてきたように、別の関数を使ってコピーするべきです。私は本当にそれに引き込まれたくはありません。それは質問の側に少し離れているからです。

呼び出し元が文字配列の長さも渡せるようにAPIを設計して、呼び出し先がバッファーをオーバーランさせないようにし、魔法の定数を使用する必要がないようにすることは賢明ですここのコードはそうです

+0

私はこれを試していますが、それでもまだ空であるため、ここで働いていないものがあります。 'int length'変数の値が' 9'であることを確認できます。 – Alexandru

+0

はい、あなたのコードには私が見たことのない間違いがありました。ごめんなさい。今修正されました。 –

+1

@Alexandru Windows APIがバッファサイズレポートをどのように管理するかの例については、[GetWindowText()](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633520(v = vs.85) ).aspx)と[GetWindowTextLength()](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633521(v = vs.85).aspx) –

関連する問題