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);

dataotherData映射到unsigned short *C 代码中。

关于返回指向已分配structs 的指针的 C 代码,您始终可以将 C# 代码包装在一个unsafe区域中,并在 C# 中使用&and*运算符。如果您构建了struct具有相同布局的有效 C#,这将按预期工作。

于 2012-11-02T17:54:22.607 回答
0

在 C# 中使用 C 的一种方法是将 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 回答