سؤال

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?

هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top