Passing StringBuilder to DLL function expecting char pointer

后端 未结 1 555
耶瑟儿~
耶瑟儿~ 2021-01-20 15:02

I\'m trying to interact with a DLL library created in Delphi. In C++, I made this call perfectly fine:

for(int y = 1; y <= 12; y++)
{
    char * chanName         


        
相关标签:
1条回答
  • 2021-01-20 15:15

    In .NET, strings (and StringBuilders) are 16-bit Unicode characters. My guess is that you native function deals in 8-bit ASCII characters. You need to tell the Marshaller how to convert the characters when marshalling them. Change your DllImport attribute like so:

    [DllImport("myDLL.dll", CharSet=CharSet.Ansi)]
    public static extern int ChannelName(int x, int y, [Out] StringBuilder z);
    

    Updated

    Also you should specify the [Out] attribute on the StringBuilder so that the Marshaller only marshals on the way out as you are passing nothing on the way in.

    Updated Again

    The [In,Out] attribute is redundant (that's the default), however putting it there makes it explicit that you know you desire both In and Out copying.

    [DllImport("myDLL.dll")]
    private static extern int ChannelName(int x, int y, [In,Out] byte[] z);
    public static int ChannelName(int x, int y, out string result)
    {
        byte[] z = new byte[100];
        int ret = ChannelName(x, y, z);
        result = Encoding.ASCII.GetString(z);
        return ret;
    }
    

    Updated Again

    It looks like the (poorly named) 'y' parameter is the length of the char * buffer passed in and my guess is that it returns the number of characters written into the buffer. If that is the case, I would wrap this invocation in a more natural C# way:

    [DllImport("myDLL.dll")]
    private static extern int ChannelName(int x, int y, [In, Out] byte[] z);
    
    public static string ChannelName(int x)
    {
        byte[] z = new byte[100];
        int length = ChannelName(x, z.Length, z);
        return Encoding.ASCII.GetString(z, 0, length);
    }
    
    0 讨论(0)
提交回复
热议问题