Younes
Younes

Reputation: 9

How to call an external function that takes pointers as input, loaded from a C++ dll

I have a C# project where I need to use an external dll.

The dll was built using C++. I have only the c++ header file (.hpp) that describes functions interfaces (signatures), and the .dll (binary code).

I want to load the dll dynamically in my C# project and use two functions :

void OpenService(long &handle);
int GetCode(long handle, const char* pin, char* passcode, char* nextPasscode, char* tokencode, char* nextTokencode);

I am able to load the dll using DllImport from System.Runtime.InteropServices and it works for the first function using the code bellow :

[DllImport(@"C:\Program Files\Path to my dll\myDll.dll")] 
    public static extern void OpenService(ref long handle); 

But for the second one, I tried the code bellow :

[DllImport(@"C:\Program Files\Path to my dll\myDll.dll")] 
    unsafe public static extern int GetCode (long handle, string* pin, string* passcode, string* nextPasscode, string* tokencode, string* nextTokencode);

But the compiler is complaining that I should use the unsafe mode while compiling to be able to use C# pointers which is something I cannot do due to rules imposed by the Tech lead.

So, my question is how can I call the second function without using C# pointers ?

I tried to use references as bellow :

[DllImport(@"C:\Program Files\Path to my dll\myDll.dll")] 
    public static extern int GetCode (long handle, ref string pin, ref string passcode, ref string nextPasscode, ref string tokencode, ref string nextTokencode);

But the program crashes whenever I call GetCode.

Any idea on how can I solve this problem ?

Thank you in advance.

Upvotes: 0

Views: 772

Answers (1)

Isma
Isma

Reputation: 15190

Instead of using unsafe and pointers you can marshal (transform) the string to a char* type using the MarshalAs method:

[DllImport(@"C:\Program Files\Path to my dll\myDll.dll")] 
public static extern int GetCode (long handle,  [MarshalAs(UnmanagedType.LPStr)]string pin,  [MarshalAs(UnmanagedType.LPStr)]string passcode,  [MarshalAs(UnmanagedType.LPStr)]string nextPasscode,  [MarshalAs(UnmanagedType.LPStr)]string tokencode,  [MarshalAs(UnmanagedType.LPStr)]string nextTokencode);

UnmanagedType.LPStr means that the string will be marshalled as

A pointer to a null-terminated array of ANSI characters.

If you need unicode you can use UnmanagedType.LPWStr

Here is more info:

https://learn.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-strings

Upvotes: 1

Related Questions