7

私はいくつかの C コードを持っており、C# から使用しようとしています。ほとんどの変換が行われます。ただし、いくつか問題があります。

「C」コードの一部は次のようになります。

typedef struct r_GetCPL {

  UInt8 Storage;
  UInt8 Key[16];             //(1) 

  UInt8 *Buff;               //(2)
  Array16 *CryptoKeyIDs;     //(3)

} REPLY_GETCPL;

「C」で定義されたエイリアス

typedef unsigned char      UInt8;
typedef unsigned short     UInt16;
typedef unsigned long      UInt32;
typedef unsigned long long UInt64;

typedef UInt8   Array8[8];
typedef UInt8   Array16[16];
typedef UInt8   Array32[32];
typedef UInt8   Array64[64];
typedef UInt8   Array128[128];

typedef を直接の構造体定義に置き換えることができると仮定しています。これでいいですか?私が定義した同等の C# 構造体は、

public struct REPLY_GETCPL 
{
  Byte Storage;
  Byte[16] Key;          //(1) Is this right?

  UInt8 *Buff;           //(2)  What is the equivalent?
  Array16 *CryptoKeyIDs; //(3)  What is the equivalent?
}

また、私が立ち往生しているインポート方法がいくつかあります

void hex_print(char* data, UInt32 length);
DRMKLVItem *NewDRMKLVItem(UInt32 lenBuff, UInt32 cmdId);
RESULT DRMKLVLengthDecode(const UInt8 *s, UInt32 *pLen);

C#

//I think this one is defined right
[DllImport("DoremiSource.dll")]
public static extern void hex_print([MarshalAs(UnmanagedType.LPStr)]string data, UInt32 length);

//(How to convert the function return type?)
[DllImport("DoremiSource.dll")]
public static extern DRMKLVItem *NewDRMKLVItem(UInt32 lenBuff, UInt32 cmdId);  //(4)

//(How do i convert the function parameters here)
[DllImport("DoremiSource.dll", CharSet = CharSet.Ansi)]
public static extern int DRMKLVLengthDecode(const UInt8 *s, ref UInt32 pLen);  //(5)
4

5 に答える 5

3

複雑な型を使用して、C と C# の間でそれらをマーシャリングできます。構造体のコンパイル オプションについて知っておく必要があるだけで、次のように C# 型を装飾できます: ( MSDNから)

[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
public class MySystemTime 
{
   [FieldOffset(0)]public ushort wYear; 
   [FieldOffset(2)]public ushort wMonth;
   [FieldOffset(4)]public ushort wDayOfWeek; 
   [FieldOffset(6)]public ushort wDay; 
   [FieldOffset(8)]public ushort wHour; 
   [FieldOffset(10)]public ushort wMinute; 
   [FieldOffset(12)]public ushort wSecond; 
   [FieldOffset(14)]public ushort wMilliseconds; 
}
于 2012-11-13T17:19:57.707 に答える
0

引数UInt8 *は、C# の配列で表すことができます。つまり、C コードへの呼び出しはUInt8[]型で行う必要があります。

本番コードの例:

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern void CCode(ushort[] data, ushort[] otherData, int width, int height);

dataC コードでは にマップotherDataされます。unsigned short *

割り当てられた s へのポインターを返す C コードに関してstructは、いつでも C# コードをunsafe領域でラップし、C# で&and*演算子を使用できます。struct同じレイアウトで有効な C# を構築した場合、これは期待どおりに機能します。

于 2012-11-02T17:54:22.607 に答える
0

C# から C を使用する 1 つの方法は、C コードを C++/CLI オブジェクトにラップすることです。

C++/CLI は、安全なコードと安全でないコードの両方を操作するのに特に適しています。C# や C でできることは何でもできます。

マネージド オブジェクトを作成してインターフェイスを定義し、(静的) 関数を入力してアンマネージド C コードを呼び出します。各関数では、引数と結果をマネージド コードからアンマネージド コードに、またはその逆に変換するために必要なマーシャリングを実行できます。

そうすれば、インターフェイスを完全に制御でき、デバッグ用の優れたアクセス ポイントが得られます。

于 2012-11-02T16:57:34.997 に答える
-1

ポインタを使用したい場合は、安全でないブロックが必要です。このサイトを見てください。

于 2012-10-31T14:16:11.030 に答える
-1

C# に「変換」しようとしている場合は、構造体ではなくクラスを使用することをお勧めします。

たとえばstruct REPLY_GETCPL、ポインタも使用しようとしていることがわかるので、クラスとしての方がよいでしょう。また、クラスに入れ、そのクラスのオブジェクト内で組み合わせた機能を使用できる構造体に関連付けられた特定のメソッドがあります。

于 2012-10-29T09:40:58.867 に答える