我一直在研究使用 OpenCV 进行一些跟踪的 DLL。使用 VS 2008(出于测试目的)在 C 控制台项目上一切正常。然后我创建了一个新的DLL项目并对其进行编译。我设置了所有内容,因此我只是将一个函数放在 Thread 类上来调用单个函数。
然后我为 GUI 和其他东西创建了一个 C# 项目。 DLL 加载正常(使用 System.Runtime.InteropServices,该方法启动(我可以看到 OpenCV 创建的捕获窗口),但跟踪尚未完成。为了验证 DLL 是否确实工作,我加载到 Python 上并调用该方法,它运行良好(正在进行跟踪)。
我刚开始在托管代码上使用非托管 DLL。关于我做错了什么或者如何调试这个有什么想法吗?如果您需要其他任何东西来帮助我解决这个问题,我会提供。
提前致谢。
编辑:
我没有在 DLL 上使用类,我使用的是单个函数,Thread 类来自 C# 上的 System.Threading
我使用DLL的方式是这样的。
namespace GUI
{
static class NativeTracking
{
[DllImport(@"__Tracking.dll")]
public static extern void _Tracking();
}
}
我把它放在像他一样的线程上
public GUI()
{
InitializeComponent();
_tracking = new Thread(_Tracking);
_tracking.Start();
}
public _Tracking()
{
while(True)
{
NativeTracking.Tracking();
}
}
编辑: native 编码
原生代码,抱歉格式困惑。
头文件
#include <cv.h>
#include <stdio.h>
#include <ctype.h>
#include <windows.h>
#include <highgui.h>
#include "..\original\project\myheader.h"
#include "..\original\project\myheader1.h"
#include "..\original\project\myheader2.h"
#include "..\original\project\myheader3.h"
#include "..\original\project\myheader4.h"
#ifdef __cplusplus
extern "C"{
#endif
_declspec(dllexport) void Tracking();
#ifdef __cplusplus
}
#endif
实现
#include "exposed.h"
void Tracking( )
{
int flag = 1, i=0;
iplImgs imgs;
trackingTool tools;
helperTools helperTools;
CvCapture* capture = 0;
capture = cvCaptureFromCAM( 0 );
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FPS, 20.0f);
imgs.image = 0;
cvNamedWindow( "Window", 0 );
initHelperTools(&helperTools);
initTools(&imgs, &tools);
for(;;){
int c;
IplImage* frame = 0;
frame = cvQueryFrame( capture );
if( !frame )
break;
if( !imgs.image ){
/* allocate all the buffers */
prepareImages(&imgs, &tools, frame);
}
cvCopy( frame, imgs.image, 0 );
cvCvtColor( imgs.image, imgs.grey, CV_BGR2GRAY );
if( flag == 1 || conditionB ){
someOperations(&imgs, &tools);
if (conditionC)
flag = 0;
}
else if( conditionD ){
otherOps(&helperTools, imgs.grey);
someTrack(&imgs, &tools, &helperTools, drawPoints);
someCorrections(&tools);
if ( condition ){
if (!wasReset){
wasReset = 0;
continue;
}
if ( validation )
someMoreOperations(&tools, corretions);
}
}
bufferHandlingOps(&imgs);
c = cvWaitKey(10);
if( (char)c == 27 )
break;
switch ((char)c){
case 'p':
drawPoints ^= 1;
break;
default:
;
}
}
cvReleaseCapture( &capture );
cvDestroyWindow("Window");
}
最佳答案
我看到的一个问题是,您在 native 代码中使用默认的 C 调用约定,即“__cdecl ”,并且在您的 P/Invoke“DLLImport”属性中,您让它使用默认调用对于 C# 来说是“__stdcall ”。每当您调用 native 方法时,这可能会引发运行时异常。
此外,我意识到您没有传递任何参数或期望任何结果,但调用约定确实表示函数的装饰方式,这可能导致 name mangling问题。 您可以:
- 将 native 导出更改为“__declspec(dllexport) void __stdcall Tracking();”
- 或者更改 DLLImport 属性上的“CallingConvention ”属性:[DllImport(@"__Tracking.dll") CallingConvention = CallingConvention=CallingConvention.Cdecl]
关于c# - C# 中的非托管 DLL 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6400075/