【发布时间】:2018-08-20 13:56:22
【问题描述】:
我正在尝试实现从 C# Unity 到 C++ 的异步接口。
这是 C++ 中公开的函数:
struct Vector3 {
float x;
float y;
float z;
};
extern "C" {
DLLEXPORT void sync_test(void*(Vector3[], int));
DLLEXPORT void async_test(void*(Vector3[], int));
}
它们是这样实现的:
void do_work(void*(onResult)(Vector3[], int)) {
int size = 30;
Vector3* result = new Vector3[size];
for (int i = 0; i < size; i++) {
result[i] = { 5,(float)i,2 };
}
onResult(result, size);
delete[] result;
}
DLLEXPORT void sync_test(void*(onResult)(Vector3[], int)) {
do_work(onResult);
}
DLLEXPORT void async_test(void*(onResult)(Vector3[], int)) {
std::thread thread(do_work, onResult);
}
这就是我在 C# 中使用它们的方式:
[DllImport("Isosurfaces.dll")]
static extern void async_test(Action<IntPtr, int> onResult);
[DllImport("Isosurfaces.dll")]
static extern void sync_test(Action<IntPtr, int> onResult);
// Use this for initialization
void Start () {
sync_test(OnResult);
//async_test(OnResult);
}
private void OnResult(IntPtr result, int size) {
Vector3[] tris = GetTris(result, size);
Debug.Log(tris[size - 1]);
}
Vector3[] GetTris(IntPtr result, int size) {
Vector3[] tris = new Vector3[size];
int vec3Size = Marshal.SizeOf(new Vector3());
for (int i = 0; i < size; i++) {
tris[i] = (Vector3)Marshal.PtrToStructure(new IntPtr(result.ToInt32() + (i * vec3Size)), typeof(Vector3));
}
return tris;
}
在统一运行项目时,sync_test 可以完美运行。打印的 Vector3 与在 C++ 端创建的相匹配。
改为调用async_test 时,Unity 会关闭且不显示错误消息。查看Editor.log 我看不到任何可能与关闭有关的信息。在同一文件夹中查看upm.log,我发现:
{"level":"error","message":"[Unity Package Manager (Upm)]\nParent process [12276] was terminated","timestamp":"2018-08-20T13:37:44.029Z"}
但这并没有给我太多关于发生了什么的背景信息。
我怀疑这与我的 C++ 代码有关。我有一段时间没有用 C++ 编程了,所以可能有一些内存我忘记释放了。但是到目前为止,我看到的唯一分配的内存是do_work 中的Vector* result,并且在C# 端处理完结果后它是免费的。
编辑:将do_work 中的delete result 更改为delete[] result,但Unity 仍然崩溃。
【问题讨论】:
-
您的
do_work函数调用未定义行为,因为它使用delete而不是delete[] -
hmmm,那它被
sync_test调用时是怎么回事? -
未定义行为的一个可能结果是代码在某些情况下“正常”工作。 undefined这个词意味着你无法保证会发生什么。
-
thread::~thread()调用std::terminate如果它有关联的可连接线程。 -
是的,现在我想起来了!但不幸的是,使用 delete[] 会出现同样的问题。 @UnholySheep
标签: c++ multithreading unity3d asynchronous dllexport