我目前正在做一个截止日期很短的项目,所以我没有太多时间来了解所有内容。另外,我不是C++ 开发和内存管理方面的专家。
所以,我想做的是用 C 和 C++ 代码创建一个 DLL。然后,我想在 C# 代码中调用这个 DLL。目前,C++ 和 C# 之间的通信正常。当我尝试将字符串从 DLL 传输到 C# 代码时,问题就出现了。错误是这个:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Microsoft.Win32.Win32Native.CoTaskMemFree(IntPtr ptr)
at System.StubHelpers.CSTRMarshaler.ClearNative(IntPtr pNative)
at NMSPRecognitionWrapper.Program.GetResultsExt()
at NMSPRecognitionWrapper.Program.<Main>b__0() in <my dir>\Program.cs:line 54
at NMSPRecognitionWrapper.Program.StartRecognitionExt()
at NMSPRecognitionWrapper.Program.Main(String[] args) in <my dir>\Program.cs:line 60
另外,我可以在下面给你一些代码(真的很简化!)。实际上,C++ 公开了两种方法:StartRecognition()
启动操作以从麦克风获取一些数据,然后处理它们并存储结果。GetResults()
返回先前存储的结果的实例。允许在WrapperCallback()
Result 能够处理时调用 C# 部分。C# 部分,当 Callback 被调用时,将要求使用该GetResults()
方法获取结果。
我知道架构在这个演示中可能看起来真的不合适,但我不想解释整个项目来验证模型,请确保一切都是正确的。
最后,问题在于 C# 回调何时调用该GetResults()
方法。尝试resultsForCS
从 C# 访问似乎是不可能的。
C++ 部分 - 标头
// NMSPRecognitionLib.h
#pragma once
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) char* GetResults();
extern "C" static void DoWork();
extern "C" __declspec(dllexport) void StartRecognition();
C++ 部分 - 来源
#include "stdafx.h"
#include "NMSPRecognitionLib.h"
static char * resultsForCS;
static SUCCESS ProcessResult(NMSPCONNECTION_OBJECTS *pNmspConnectionObjects, LH_OBJECT hResult)
{
[...]
char* szResult;
[...]
resultsForCS = szResult;
DoWork();
[...]
return Success;
error:
return Failure;
} /* End of ProcessResult */
extern "C" __declspec(dllexport) char* GetResults()
{
return resultsForCS;
}
extern "C"
{
typedef void (*callback_function)();
callback_function gCBF;
__declspec(dllexport) void WrapperCallback(callback_function callback) {
gCBF = callback;
}
static void DoWork() {
gCBF();
}
}
extern "C" __declspec(dllexport) void StartRecognition()
{
char* argv[] = { "path", "params" };
entryPoint(2, argv);
}
C#部分
class Program
{
[DllImport("NMSPRecognitionLib.dll", EntryPoint = "GetResults")]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string GetResultsExt();
public delegate void message_callback_delegate();
[DllImport("NMSPRecognitionLib.dll", EntryPoint = "WrapperCallback")]
public static extern void WrapperCallbackExt(message_callback_delegate callback);
[DllImport("NMSPRecognitionLib.dll", EntryPoint = "StartRecognition")]
public static extern void StartRecognitionExt();
static void Main(string[] args)
{
WrapperCallbackExt(
delegate()
{
Console.WriteLine(GetResultsExt());
}
);
StartRecognitionExt();
Console.WriteLine("\nPress any key to finish... ");
var nothing = Console.ReadLine();
}
}
我知道问题的出现是因为我使用指针来存储结果(char *
),但我实际上不知道如何以另一种方式做到这一点。szResults
类型char *
也是,我不能改变这个!