3

我是 C# 和编组的新手。我需要在 C# 中使用我的 C func,但我的 C func 返回值不正确(或者我不知道如何将其转换为正确答案)。

C源:

#include "main.h"

char *Ololo(char *arg, int &n3)
{
    char *szRet;
    szRet=(char*)malloc(strlen(arg)+1);
    strcpy(szRet,arg);
    n3 = strlen(szRet);
    return szRet;
}

C头文件:

extern "C" __declspec(dllexport) char *Ololo(char *arg, int &n3);

C#源代码:

class Program
{
    [DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
    public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3);

    static void Main(string[] args)
    {
        string n1 = "ololo";
        char[] chars = new char[n1.Length];
        chars = n1.ToCharArray();
        Int32 n3 = 0;
        IntPtr result;
        result = Ololo(chars, ref n3);
        string n4 = Marshal.PtrToStringUni(result,n3);
        Console.WriteLine(n4);
    }
}

我有返回类似“o???”的东西

对不起英语不好

- - - - - - - - - - - 解决了 - - - - - - - - - - - -

class Program
    {
        [DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        public static extern IntPtr Ololo([MarshalAs(UnmanagedType.LPStr)]string arg, ref Int32 n3);

        static void Main(string[] args)
        {
            string n1 = "ololo";
            Int32 n3 = 0;
            int n2 = n1.Length;
            IntPtr result;
            result = Ololo(n1, ref n3);
            string n4 = Marshal.PtrToStringAnsi(result, n3);
            Console.WriteLine(n4);
        }
    }

这很好用。在 n3 我有 5 和在 n4 ololo!感谢您的快速回答!

4

2 回答 2

3

public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3);

IntPtr是错误的返回类型,因为本质上您想要返回字符串,而不是指向字符串的指针。在 C 中,您可以通过 using 使用指向字符串的指针char*,在 .NET 中的等价物是使用 use this: [MarshalAs(UnmanagedType.LPStr)]string。这应该char* 正确编组string

IntPtr表示一个指针类型,获取你的实际字符串是没有用的。

看起来您应该将 aStringBuilder纳入编组函数,而不是char[]. 那么至少你应该得到正确的字符串到你的 C 函数。

于 2012-09-10T11:52:17.123 回答
-1

编组器不会 NULL 终止char有趣的数组。它会这样做,因为你告诉它——如果你告诉它。你很幸运,因为char.NET 中的 a 是 UTF-16,这是 16 位宽 - 第二个字节将为零,因为它是'o'UTF-16,因此 strlen 为 1。传递托管的实际努力string 作为一个以 null 结尾的 C 字符串,比你想象的要高一点。所以让编组器完成所有工作——它已经知道如何完成这项工作。

public static extern [MarshalAs(UnmanagedType.LPStr)]string Ololo(
    [MarshalAs(UnmanagedType.LPStr)]string arg,
    ref int n3
);
static void Main(string[] args)
{
    string n1 = "ololo";
    Int32 n3 = 0;
    string n4 = Ololo(chars, ref n3);
    Console.WriteLine(n4);
}
于 2012-09-10T12:03:05.473 回答