2012-03-24 7 views
4

私はアンマネージドDLL(Cコード)で多くの未知のサイズの配列が含まれている構造体を持っているアンマネージDLLから、ダイナミックアレイを含むcsharpの構造体にアクセスするにはどうすればよいですか?私のCコード-In

-Iは私がするC#にオーバーマーシャリング本の1つのインスタンスは、構造体のデータを必要とします後で非管理のCコードに送り返す

- このデータをcsharpに変換した後は、このデータを操作する必要はなく、しばらく保持する(バイト配列に残すことができます)。

- 「unsafe」というキーワードを使用したくないのは、大きなプロジェクトであり、これはちょうど小さな作品であり、私はそのようにコンパイルしたくありません。

私はlpArrayとしてマーシャリングを試みましたが、すべてがうまく見えますが、私はcsharpに戻った後に内容を見ると、常に空です。このタイプのマーシャルスタイルは、構造体ではなく、さまざまな型の動的配列に対して私の仕事をしてくれました。

ウェブの検索では空白があり、自分よりもはるかに複雑なシナリオがありますが、誰かがこのようなリンクを見た場合は、ここに投稿してください。

ありがとうございました。

--updateはここにある、多かれ少なかれ私のコードの構造:

のC#:

[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
private static extern int W_Thread_Connect_NET(
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 100)] string IPAddress, 
    int DevicePort, 
    [MarshalAs(UnmanagedType.LPArray)] byte[] connectionHandle 
); 

//and call it like this, with an empty struc to be populated by c (can this be done? it is comming back without the data): 
byte[] myStrucParam= new byte[100]; 
int result = W_Thread_Connect_NET(myStrucParam, myParam1, myParam2, ...); 

C:

typedef struct myStructDef{ 
    char* myArray1, 
    char* myArray2, 
    int myInt1, 
    ... 
} mystrucObj, *pMystrucObj; 

//method that i am wanting to marshal the struct as a paramter here.. 
MYDLL_DLLIMPORT int APIENTRY W_Thread_Connect_NET(pMystrucObj strucReturn_handle, char * IPAddress, int DevicePort, ...) 
    { 
     //(omitted) 
    } 
+3

構造体のC宣言と構造体を受け取るネイティブ関数のC宣言を見てください。それから、あなたが必要とするピンボケを見せることができます。 –

+0

デビッドありがとう - 私は何の仕事をしているのと同じようなコードを少し追加しました。実際には実際のコードを貼り付けることはできません。なぜなら、そのコードは大きくて面倒で、実際に共有することはできないからです。しかし、もし私が他の情報を私に含める必要がある場合、私に教えてください。 – Chris

+0

構造体はどこから生成されますか? C文字列はどのように割り当てられますか? –

答えて

2

あなたはC#コードをする必要がないことを言います構造体を操作します。それは解決するのがかなり簡単な問題になります。構造体ポインタを不透明なポインタ、つまりIntPtrとして扱うことができます。

あなたのネイティブコードに新しい機能を追加するまず第一に:

pMystrucObj CreateStruct(void) 
{ 
    pMystrucObj res = malloc(sizeof(*res)); 
    return res; 
} 

は、その後、あなたのC#コードで、あなたはこのようにそれを呼び出す:

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] 
private static extern IntPtr CreateStruct(); 

さて、このようなW_Thread_Connect_NETを宣言:

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] 
private static extern int W_Thread_Connect_NET(
    IntPtr theStructPtr, 
    string IPAddress, 
    int DevicePort, 
    .... 
); 

これを次のように指定します。

IntPtr theStructPtr = CreateStruct(); 
int res = W_Thread_Connect_NET(theStructPtr, IPAddress, DevicePort, ...); 

もちろん、完了したら構造体のメモリの割り当てを解除するために、DestroyStructという別の関数を追加したいと思うでしょう。

関連する問題