日期:2014-05-18  浏览次数:21331 次

C#调用非托管代码:无法封送处理“return value”: 无效的托管/非托管类型组合
我用C++写了一个接口,并编译为dll: 我想要的效果是从这个dll中返回一个数组给C#的代码。
C/C++ code
extern "C" __declspec(dllexport) int* TestSetArray(IN int arr[1024])
{
    for(int i=0;i < 99; i++)
    {
        arr[i] = i;
    }

    return arr;
}code]

C#调用:
[code=C#][DllImport("TestDLL.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add(int a, int b);

[DllImport("TestDLL.dll",
            EntryPoint = "TestSetArray",
            ExactSpelling = true,
            CallingConvention = CallingConvention.Cdecl,
            CharSet = CharSet.Ansi)]
        public static extern int[] TestSetArray([MarshalAs(UnmanagedType.LPArray)] int[] arr);

static unsafe void Main(string[] args)
        {
            Console.WriteLine(Add(1,2));
            Console.WriteLine();

            int[] arr = new int[1024];           
            int[] arr1 = TestSetArray(arr);

            Console.WriteLine();
            Console.Read();
            
        }


当运行到int[] arr1 = TestSetArray(arr);时,
编译提示错误:无法封送处理“return value”: 无效的托管/非托管类型组合。

请大侠帮我解答,谢谢了

------解决方案--------------------
int[] 
的非托管对应于 
SAFEARRAY
------解决方案--------------------
指的是 你的非托管函数必须返回 SAFEARRAY。
这样托管签名才能是 int[].
------解决方案--------------------
尝试
[return:MarshalAs(...)] 
试试。

------解决方案--------------------
如果你的非托管函数已经是固定的。
那么需要修改托管签名。
因为返回的是一个指向非托管的指针引用。
所以必须是 IntPtr。
然后使用 Mashal 函数来读取这个非托管内存。