.No。
。自分で行う必要があります。
.Yes
あなたがCまたはC++側の関数の内部メモリを割り当てる場合は、それを解放しなければなりません。私はサイドにメモリを割り当てるコードは見当たりませんが、あなたはその部分を残したと思います。また、スタック上で宣言された変数をC#に返さないでください。クラッシュを含む未定義の動作に終わります。
Hereは、このためのC++ソリューションです。
C溶液について:
char* getByteArray()
{
//Create your array(Allocate memory)
char * arrayTest = malloc(2 * sizeof(char));
//Do something to the Array
arrayTest[0]=3;
arrayTest[1]=5;
//Return it
return arrayTest;
}
int freeMem(char* arrayPtr){
delete[] arrayPtr;
free(arrayPtr);
return 0;
}
唯一の違いは、Cバージョンはメモリを割り当て、デ割り当てるmalloc
とfree
機能を使用することです。
C#:
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getByteArray();
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
public static extern int freeMem(IntPtr ptr);
//Test
void Start()
{
//Call and return the pointer
IntPtr returnedPtr = getIntArray();
//Create new Variable to Store the result
byte[] returnedResult = new byte[2];
//Copy from result pointer to the C# variable
Marshal.Copy(returnedPtr, returnedResult, 0, 2);
//Free native memory
freeMem(returnedPtr);
//The returned value is saved in the returnedResult variable
byte val1 = returnedResult[0];
byte val2 = returnedResult[1];
}
注この2文字のみとチャーを使用する唯一の試験であること。文字列の動的サイズは、out int outValue
パラメータをC#関数に追加してから、int* outValue
パラメータをC関数に追加することで動的にすることができます。 C面のこのパラメータに文字のサイズを書き込んで、そのサイズをC#側からアクセスできます。
このサイズは、Marshal.Copy
関数の最後の引数に渡すことができ、現在のハードコーディングされた2の値の制限値を削除します。私はこれをあなたのために残しておきますが、混乱した場合は、その例のthisを参照してください。
より良い解決策は、それに書き込むネイティブ側にStringBuilder
を渡すことです。悪い点は、StringBuilder
のサイズを時間通りに宣言しなければならないことです。
C++:
void __cdecl _GetLookupStatus (char* data, size_t size)
{
strcpy_s(data, size, "Test");
}
C#の:あなたは、あなたがC#の側に文字列を使用する必要があります最速の方法を探しているなら
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
public static extern int _GetLookupStatus(StringBuilder data, int size);
//Test
void Start()
{
StringBuilder buffer = new StringBuilder(500);
_GetLookupStatus (buffer, buffer.Capacity);
string result = buffer.ToString();
}
、それをピンC#側では、IntPtr
としてCに送信します。 C側では、strcpy_s
を使用してchar配列を変更できます。そうすれば、C側にメモリは割り当てられません。 C#のchar配列のメモリを再利用しています。回答hereの最後には、float[]
の例があります。
詳細な説明をありがとうございました!コードスニペットにMakeStringCopy()を追加しました。 –
スタックに渡される変数を返さないことに関するもう1つの質問:プリミティブデータ型にも当てはまりますか?私はいくつかのテストとストリングを即座に失敗しましたが、intはうまくいくようです。 –
int、float、boolの場合は問題ありません。あなたが '&'またはそれのポインタに '*'をつけてその参照を返すのであれば、それはうまくありません。 'int []'や 'int *'のような配列の場合は、そのメモリアドレスを返すのでうまくいきません。 C++の 'malloc'やC++の' new'キーワードで作成された変数であれば、関数の外にあってもそこに存在するので、問題ありません。私は関数内で参照やポインタを返すことについて学ぶべきだと思います。あなたはこれらを完全に理解するでしょう。 – Programmer