2017-02-24 16 views
2

私は通常、あなたは、単にこのためC++ライブラリを書くことができますし、ちょうど私がC#のライブラリを開発していると私がしたいマーシャルのconstのchar **

int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argCnt); 

この機能を実装するアルマ3の拡張子を書いていますこの機能を実装します。機能RVExtensionArgsは、私はargs引数のconstのchar型のポインタへのポインタに苦しんだ64ビット

のために32ビットのための[email protected]RVExtensionArgsで装飾された名前を持っています。私の現在のimplementionはDLLEXPORTを使用

#if WIN64 
    [DllExport("RVExtensionArgs", CallingConvention = CallingConvention.Winapi)] 
#else 
    [DllExport("[email protected]", CallingConvention = CallingConvention.Winapi)] 
#endif 
    public static int RvExtensionArgs(StringBuilder output, int outputSize, 
     [MarshalAs(UnmanagedType.LPStr)] string function, 
     [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4, ArraySubType = UnmanagedType.LPStr)] string[] args, 
     int argCount) 

あるUnmanagedExports

からであるhere

以上の拡張機能に関するいくつかの情報しかし、この方法でゲームがクラッシュがあります。私はこれがargsのためだと確信していますが、私はそれを確認することはできません。何か不足していますか?

+0

例外メッセージは一切ありますか? – pquest

+0

悲しいことに、有用なデバッグ情報はありません。この場合は、DLLはゲームから読み込まれ、ゲームはデバッグできないため、私は何もデバッグできません。私も通常のRVE拡張を実装しました(リンクされたwikiページにあります)。これはうまくいきます。 – chris579

+2

マーシャリングの推測を推測するために、byte *出力、int outputSize、byte *関数、byte ** args、int argCntのような安全でないクラスにインポートする方が簡単でパフォーマンスが向上しますか?唯一の「挑戦」は、.NET文字列のUTF-16文字をバイトに変換することです。 – hoodaticus

答えて

1

私は質問へのコメントに答えましたが、const char**をC#からC++にエクスポートする最も簡単な方法は、byte**です。

私は以下のStringMarshallerクラスを作成して、byte **をstring []に変換するのを手伝っています。私はまだそれをテストしていない - 私は後でする時間があります、もしそうなら更新します。

public unsafe static class StringMarshaller 
{ 
    public static string[] Marshal(byte** nativeStrings, int stringCount) 
    { 
     var strings = new string[stringCount]; 

     for (var x = 0; x < stringCount; ++x) 
     { 
      if (nativeStrings[x] == null) continue; 
      var length = GetStringLength(nativeStrings[x]); 
      strings[x] = length == 0 
        ? string.Empty 
        : Encoding.UTF8.GetString(nativeStrings[x], length); 
     } 

     return strings; 
    } 

    public static int GetStringLength(byte* nativeString) 
    { 
     var length = 0; 

     while (*nativeString != '\0') 
     { 
      ++length; 
      ++nativeString; 
     } 

     return length; 
    } 
} 
+1

CallingConvention.Winapiを使用する必要があるか、dllが認識されて読み込まれていないことが判明しました。あなたの現在の例がうまくいきませんので、私は編集を提案しました:) – chris579

+0

@ chris579 - 申し訳ありませんが、審査委員会は、私がやり遂げる前にあなたの編集を手に入れました。私はあなたの変更が必要であった理由を正確にはわかりませんが、重要なのはそれを働かせていることです。あなたは今良いですか? – hoodaticus

+1

Encoding.UTF8.GeStringはバイトポインタを直接処理できないため、編集が必要でした。最初にバイト配列にマーシャリングする必要があります。でも今は大丈夫です – chris579

関連する問題