由网友(余光)分享简介:我用C++创建了一个可在Windows和Mac OSX上编译的跨平台DLL。在Windows上,我有一个使用P/Invoke调用DLL的C#应用程序,而在Mac OSX上,一个Objective C应用程序调用DLL。我有一些简单的函数可以很好地工作,但我需要一个返回整数数组的新函数。我能找到的最好的例子是Marsha...![利用VB,编写一个3 4的二维数组输入任意整数,求所有数组元素和及平均值](https://p.xsw88.cn/allimgs/daicuo/20230903/2588.png)
我用C++创建了一个可在Windows和Mac OSX上编译的跨平台DLL。在Windows上,我有一个使用P/Invoke调用DLL的C#应用程序,而在Mac OSX上,一个Objective C应用程序调用DLL。我有一些简单的函数可以很好地工作,但我需要一个返回整数数组的新函数。
我能找到的最好的例子是Marshal C++ int array to C#,我能够让它工作。但是,我想修改此示例,将整数数组作为引用参数传回。数组的大小必须在运行时设置。
![利用VB,编写一个3 4的二维数组输入任意整数,求所有数组元素和及平均值](https://p.xsw88.cn/allimgs/daicuo/20230903/2588.png)
以下是我尝试过的方法。PSize正在正确返回,但列表为空。
在非托管C++中:
bool GetList(__int32* list, __int32* pSize)
{
// Some dummy data
vector<int> ret;
ret.push_back(5);
ret.push_back(6);
list = (__int32*)malloc(ret.size());
for (unsigned int i = 0; i < ret.size(); i++)
{
list[i] = ret.at(i);
}
*pSize = ret.size();
return true;
}
在C#中:
[DllImport(@"MyDll.dll",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern bool GetList(out IntPtr arrayPtr, out int size);
public static int[] GetList() {
IntPtr arrayValue = IntPtr.Zero;
int size = 0;
bool b = GetFrames(out arrayValue, out size);
// arrayValue is 0 here
int[] result = new int[size];
Marshal.Copy(arrayValue, result, 0, size);
return result;
}
推荐答案
您的问题是list
的定义,它确实需要是__int32**
才能传回分配的数组的地址。为了轻松解决互操作中指针指向指针的困难,如果失败,则返回list
或null
的地址如何:
__int32* GetList(__int32* pSize)
{
// Some dummy data
vector<int> ret;
ret.push_back(5);
ret.push_back(6);
// per @David's catch, you'll need to allocate the right amount
__int32* list = (__int32*)malloc(ret.size() * sizeof(__int32));
for (unsigned int i = 0; i < ret.size(); i++)
{
list[i] = ret.at(i);
}
*pSize = ret.size();
return list;
}
void RemoveList(__int32* list)
{
free(list);
}
对您的C#进行适当修改:
[DllImport(@"MyDll.dll",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetList(out int size);
[DllImport(@"MyDll.dll",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern void RemoveList(IntPtr array);
public static int[] GetList()
{
int[] result = null;
int size;
IntPtr arrayValue = IntPtr.Zero;
try
{
arrayValue = GetList(out size);
if (arrayValue != IntPtr.Zero)
{
result = new int[size];
Marshal.Copy(arrayValue, result, 0, size);
}
}
finally
{
// don't forget to free the list
RemoveList(arrayValue);
}
return result;
}
相关推荐
最新文章