【发布时间】:2014-01-30 02:28:52
【问题描述】:
我为 c++ dll 创建了一个 c# 包装器,但我没有 c++ dll 的源代码。现在 c++ 有一个委托函数,我在 c# 包装器中创建了委托函数并为其提供了必要的参数。 面临的问题是,每当委托功能完成时,我都会收到内存不足异常,并且我还发现委托使用了一个新线程。我将演示下面的代码:
1) C# 包装器
public struct WISCN_RUN_OPTS
{
public uint Version;
public WISCN_CALLBACK_CODELINE_DONE CodelineDoneCallback;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public delegate bool WISCN_CALLBACK_CODELINE_DONE(
uint doc_index,
uint user_data,
uint codelines_count,
WISCN_CODELINE[] codelines,ref
WISCN_CODELINE_DOC_CTRL p_doc_ctrl);
[DllImport(@"wiscn.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern WISCN_ERROR WiScn_Run(_WISCN_HINST_STRUCT hinst, uint num_of_docs, ref uint p_docs_done, ref WISCN_RUN_OPTS p_opts);
2) C# windows 应用程序
private void ButtonProcessDocsWithOcr_Click(object sender, EventArgs e)
{
var run_opts = new DllLoad.WISCN_RUN_OPTS
{
Version = DefineConstants.WISCN_STRUCT_VERSION_RUN_OPTS
CodelineDoneCallback = DocDoneCallback;
};
//The callback delegate is called when this method is triggered
WiScn_Run(hinst, 0, ref docNum, ref run_opts);
}
bool DocDoneCallback(uint doc_index, uint user_data,
uint codelines_count,
WISCN_CODELINE[] codelines,ref
WISCN_CODELINE_DOC_CTRL p_doc_ctrl)
{
return false;
}//After this line i receive the out of memory exception
// when it tries to resume ButtonProcessDocsWithOcr_Click event.
3) C++ 封装头文件
typedef struct
{
DWORD Version;
WISCN_CALLBACK_CODELINE_DONE CodelineDoneCallback;
}
WISCN_RUN_OPTS;
typedef BOOL (*WISCN_CALLBACK_CODELINE_DONE)(DWORD doc_index,
DWORD user_data, DWORD codelines_count, const WISCN_CODELINE codelines[],
WISCN_CODELINE_DOC_CTRL *p_doc_ctrl);
typedef WISCN_ERROR (WISCN_API *WISCN_RUN)(WISCN_HINST hinst, DWORD num_of_docs, LPDWORD p_docs_done, const WISCN_RUN_OPTS *p_opts);
WISCN_ERROR WISCN_API WiScn_Run(WISCN_HINST hinst, DWORD num_of_docs, LPDWORD p_docs_done, const WISCN_RUN_OPTS *p_opts);
4) c++ 示例
BOOL DocDoneCallback(DWORD doc_index, DWORD user_data,
DWORD codelines_count, const WISCN_CODELINE codelines[],
WISCN_CODELINE_DOC_CTRL *p_doc_ctrl)
{
return FALSE;
}
void main()
{
WISCN_RUN _WiScn_Run;
WISCN_RUN_OPTS run_opts;
_WiScn_Run = (WISCN_RUN)GetProcAddress(hmod, "WiScn_Run");
run_opts.Version = WISCN_STRUCT_VERSION_RUN_OPTS;
run_opts.DocDoneCallback = DocDoneCallback;
_WiScn_Run(hinst, 0, NULL, &run_opts);
}
【问题讨论】:
-
我无法理解这一点。您谈论的是非托管代码,但这里的一切都是 C#。界面的另一边在哪里?
-
这是用c++编写的dll文件,但我没有c++的源代码,但如果有帮助,我可以添加dll包装器的c++代码
-
这是一个互操作问题。没有界面的两边是没有希望的。我们需要查看所有涉及的类型,包括 C++ 和 C#。以及所有函数声明。
-
c++ dll 包装文件可以在以下链接中找到4shared.com/file/Ui0U1cbTba/SimpleExample.html4shared.com/file/_j1rfZjXce/wiscn.html
-
显示
WiScn_Run的C# 声明和WISCN_RUN的C++ 声明。以及所有缺失的结构声明。