Call C dll code from C# through PInvoke

himanshu saxena 1 Reputation point
2022-06-28T07:34:11.64+00:00

A C dll has the following code:

struct CredPair{
char usr[127];
char pas[127];
};

struct CredData{
enum CredType {
PAIR,
KEY
} credType;
void* CredVal;
};

struct EndpointData {
enum EndpointType {
DIRECT
} endpointType;
void* endpointVal;
};

struct EndpointDirect {
char url[127];
};

and has a function declaration as:

__declspec(dllexport) MyErrCode CheckUser(const struct CredData* cred_data, const struct EndpointData* endpoint_data);

I have defined the following structures and enums in my C# code:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CredPair
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 127)]
public string usr;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 127)]
public string pas;
}

public enum CredType
{
PAIR,
KEY
}

public enum EndpointType
{
DIRECT
}

public struct CredData
{
public CredType credType;
[MarshalAs(UnmanagedType.LPStruct)]
public CredPair credVal;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct EndpointDirect
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 127)]
public string url;
}

public struct EndpointData
{
public EndpointType endpointType;
[MarshalAs(UnmanagedType.LPStruct)]
public EndpointDirect endpointVal;
}

and the function is defined as:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern MyErrCode CheckUser([In] ref CredData cred_Data, [In] ref EndpointData endpoint_data);

Here is my C# code to call the function:

CredData objCredData = new CredData
{
credType = CredType.PAIR,
credVal = new CredPair(
{
usr = "abc@xyz .com",
pas = "admin@AJAY ",
}
};
EndpointData objData = new EndpointData
{
endpointType = EndpointType.DIRECT,
endpointValue = new EndpointDirect
{
url = "example.com",
},
};
error_code = CheckUser(ref objCredData, ref objData);

This is giving me an error as:
{System.TypeLoadException: Cannot marshal field 'credVal' of type 'ConsoleApplication5.CredData': Invalid managed/unmanaged type combination (this value type must be paired with Struct).

How can I fix this?
Is there anything wrong with the declaration?

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,962 questions
{count} votes

1 answer

Sort by: Most helpful
  1. RLWA32 45,576 Reputation points
    2022-06-28T10:57:33.49+00:00

    The runtime is objecting to the attempt to marshal the embedded structure (not a reference type) as an unmanaged pointer. Since the C struct declares these members as void* pointers I suggest that you use IntPtr in your C# structs. For example, allocate the unmanaged memory for an IntPtr with Marshal.AllocHGlobal and then initialize with Marshal.StructureToPtr before using p/invoke to call the unmanaged C function.

    The site rejected my attempt to post some example code so here is a link to it on OneDrive - s!AmnqrCFBv4nDgjq2Gk4beKY82GjJ

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.