Reputation: 1284
I have some C code that and I trying to use from C#. Most of the conversion is done. I have a couple of issues though.
Part of the 'C' code looks like this.
typedef struct r_GetCPL {
UInt8 Storage;
UInt8 Key[16]; //(1)
UInt8 *Buff; //(2)
Array16 *CryptoKeyIDs; //(3)
} REPLY_GETCPL;
alias defined in '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];
I am assuming I can replace the typedef with a direct struct definition. Is this fine? The equivalent C# struct I defined is,
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?
}
Also, There are a couple of methods import that I am stuck at
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)
Upvotes: 7
Views: 1069
Reputation: 1287
You can use complex types and marshal them around between C and C#, you just have to know about the compilation option for the structure, then decorate a C# type like the following: (From 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;
}
Upvotes: 3
Reputation: 2039
Your UInt8 *
argument can be represented with an array in C#, since that is what it is. That is, your call to the C code should be made with the UInt8[]
type.
Example from production code:
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern void CCode(ushort[] data, ushort[] otherData, int width, int height);
data
and otherData
maps to unsigned short *
in the C code.
Regarding C code that returns pointers to allocated struct
s, you can always wrap your C# code in an unsafe
region and use the &
and *
operators in C#. This works as expected if you have constructed a valid C# struct
with the same layout.
Upvotes: 0
Reputation: 604
One way of using C from C# is by wrapping your C code in a C++/CLI object.
C++/CLI is particularly well suited for working with both safe and unsafe code. You can do anything that you can do in C# and C.
Define an interface by create a managed object and fill it with (static) functions to call your unmanaged C code. In each function you can do the marshalling needed for converting arguments and results from managed to unmanaged code and the other way around.
That way you keep full control over the interface and have a nice access point for debugging.
Upvotes: 0
Reputation: 208
If you want to use pointers you need a unsafe blok. Take a look at this site.
Upvotes: -1
Reputation: 88
If you are trying to "convert" to c#, better use classes instead of structures.
For Example your struct REPLY_GETCPL
would be better off as a class, since I see you are also trying to use pointers.
Also, you have certain methods associated with the struct you can put into a class and use a combined functionality inside a object of that class.
Upvotes: -1