Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export managed C# function to return changed char* parameter to unmanaged code

I have a native C++ (I think) app which can be configured to load a certain dll and call a function. This function returns int, takes in four parameters, should change at least one of the two and return a value. According to the manual this function should be defined in C++ as:

__declspec( dllexport ) int funcName(const char* par1, const char* par2, char* par3, char* par4);

However, by demand, this function should be implemented in C#. I am using Unmanaged Exports to allow me to use:

[DllExport("funcName", CallingConvention.Cdecl)]
public static unsafe int funcName(string par1, string par2, string par3, string par4) {
    // sample for par3 only when using StringBuilder instead of string
    // but is similar with other types
    par3 = new StringBuilder(256); 
    par3.Append("12345"); 
    return 0; 
}

Parameters 1 and 2 work just fine (I can messagebox the values received), however I have tried (at least) the following as the 3rd and 4th parameters:

char* =>
=> string
=> StringBuilder
=> char[]

all of these with [In], [Out], [In,Out], out, ref.

Function should change the value of par3 and par4 and return an integer back to the calling application. The application reads the value of par3 (it is actually an integer represented as string) and writes it out to the log file. After examining the log file, the value is not the one set in funcName(...).

Most commonly the value is "" (empty), however only when using char[] with out or ref there seems to be a value passed back, but it is just a few weird chars (not the value that is set in funcName).

So the question would be, how to return char* parameter when calling a managed dll function from unmanaged code?

like image 293
UяošKoт Avatar asked Jan 27 '14 10:01

UяošKoт


People also ask

What is export function C?

Exporting is relative to that process. In C/C++ if you want to declare a function to use it without defining it in a source file, you should use the keyword "extern". In the file where that function is defined you have nothing special to make, by defaults things at global scope are automatically exported.

Is C managed code?

What is Managed Code in C#? As we have seen in the beginning, the code which is developed using the Common Language Runtime (CLR) of the . NET framework is known as Managed Code. In other words, it is the code that gets executed directly in C#.

Is C++ managed or unmanaged code?

So, by that definition all code compiled by traditional C/C++ compilers is 'unmanaged code'. Also, since it compiles to machine code and not an intermediate language it is non-portable.

What is managed in C#?

Managed code is a code whose execution is managed by Common Language Runtime. It gets the managed code and compiles it into machine code. After that, the code is executed. The runtime here i.e. CLR provides automatic memory management, type safety, etc.


1 Answers

I doubt very much that UnmanagedImports will do the work for you. It won't magic a StringBuilder into existence unless I am very much mistaken. I think you need to code it like this:

[DllExport("funcName", CallingConvention.Cdecl)]
public static int funcName(string par1, string par2, IntPtr par3, IntPtr par4) 
{
    string inputStr = Marshal.PtrToStringAnsi(par3);
    string outputStr = "foo\0";
    byte[] outputBytes = Encoding.Default.GetBytes(outputStr);
    Marshal.Copy(outputBytes, 0, par3, outputBytes.Length);
    return 0; 
}

Note that I have removed the unsafe since that is not needed.

like image 83
David Heffernan Avatar answered Oct 23 '22 10:10

David Heffernan