如何在非托管C++项目中引用c# dll

邹宇华 2012-06-19 01:03:08
求教C# dll在非托管C++中的应用:目前试了两种方法,一是在项目中对引用C# dll的cpp文件开启/clr和创建对应的sydafx.h,但编译出现各种error;二是用托管C++将C# dll二次封装,在非托管项目中引用封装好的dll,编译没有问题,但是加载不了dll,启动程序出现0x000000c5错误。求教解决方案!
...全文
195 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
邹宇华 2012-06-19
  • 打赏
  • 举报
回复
哦,谢谢,我会再按照指南试试。不过目前倾向于将 C# dll 封装为 C++ dll 来调用,这样我就不需要对现有项目做大的调整。项目里只是一个类 cpp 文件需要用到 C# dll。目前我二次封装是参考了 http://blog.csdn.net/starlee/article/details/2897970#reply 的方法,头文件设置如下:

// csDll2cppDllTest.h
#pragma once

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 CSDLL2CPPDLLTEST_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// CSDLL2CPPDLLTEST_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef CSDLL2CPPDLLTEST_EXPORTS
#define CSDLL2CPPDLLTEST_API __declspec(dllexport)
#else
#define CSDLL2CPPDLLTEST_API __declspec(dllimport)
#endif

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;


// 此类是从 csDll2cppDllTest.dll 导出的
class CSDLL2CPPDLLTEST_API CcsDll2cppDllTest {
public:
CcsDll2cppDllTest(void);
~CcsDll2cppDllTest(void);
// TODO: 在此添加您的方法。
void ceddCoder(cv::Mat *img, vector<float>& code);
private:
//用一个void指针指向 CcsDll2cppDllTest 的对象
//所有公有成员函数的实现都是通过这个对象来实现
void* m_pImp;
};

cpp 文件如下:
// csDll2cppDllTest.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "csDll2cppDllTest.h"

#include <vcclr.h>
#include <string.h>
#include <stdlib.h>

#using "CEDD.dll"
#using "System.Drawing.dll"

using namespace System;
using namespace System::Runtime::InteropServices;

using namespace CEDD_Descriptor;

typedef unsigned char byte;


//将GCHandle转换成为void指针
#define __GCHANDLE_TO_VOIDPTR(x) ((GCHandle::operator System::IntPtr(x)).ToPointer())
//将void指针转换为GCHandle
#define __VOIDPTR_TO_GCHANDLE(x) (GCHandle::operator GCHandle(System::IntPtr(x)))

//辅助函数
//将void指针指向的对象转换成为CEDD对象
inline CEDD_Descriptor::CEDD^ GetImpObj(void* pHandle)
{
CEDD_Descriptor::CEDD^ cedd = nullptr;
if(pHandle != NULL)
{
cedd = static_cast<CEDD_Descriptor::CEDD^>(__VOIDPTR_TO_GCHANDLE(pHandle).Target);
}
return cedd;
}


// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 csDll2cppDllTest.h
CcsDll2cppDllTest::CcsDll2cppDllTest()
{
m_pImp = NULL;
CEDD_Descriptor::CEDD^ cedd = gcnew CEDD_Descriptor::CEDD();
//创建GCHandle并将它转换成void指针保存到成员变量中
GCHandle handle=GCHandle::Alloc(cedd);
m_pImp = __GCHANDLE_TO_VOIDPTR(handle);
}


CcsDll2cppDllTest::~CcsDll2cppDllTest()
{
if (m_pImp == NULL)
{
return;
}
// 释放 GCHandle
GCHandle handle = __VOIDPTR_TO_GCHANDLE(m_pImp);
handle.Free();
m_pImp = NULL;
}


/*----------------------------
* 功能 : 将图像格式由 cv::Mat‚ 转换为 Drawing::Bitmap‚
*----------------------------
* 函数 : encodeMatToImage
* 访问 : private
* 返回 : System::Drawing::Bitmap^ C#格式的位图
* 参数 : cv::Mat * src 输入图像
*/
inline System::Drawing::Bitmap^ encodeMatToImage(cv::Mat *src)
{
// ƒbitmap 初始化
System::Drawing::Bitmap ^dst = gcnew System::Drawing::Bitmap(
src->cols, src->rows, System::Drawing::Imaging::PixelFormat::Format24bppRgb);

// ’获取 bitmap 数据指针
System::Drawing::Imaging::BitmapData ^data = dst->LockBits(
*(gcnew System::Drawing::Rectangle(0, 0, dst->Width, dst->Height)),
System::Drawing::Imaging::ImageLockMode::ReadWrite,
System::Drawing::Imaging::PixelFormat::Format24bppRgb
);

// 获取 cv::Mat 数据地址
src->addref();

// ƒ复制图像数据
if (src->channels() == 3 && src->isContinuous()) {
memcpy(data->Scan0.ToPointer(), src->data,
src->rows * src->cols * src->channels());
}
else {
for (int i = 0; i < src->rows * src->cols; i++) {
byte *p = (byte *)data->Scan0.ToPointer();
*(p + i * 3) = *(p + i * 3 + 1) = *(p + i * 3 + 2) = *(src->data + i);
}
}

// ’解除 bitmap 数据保护
dst->UnlockBits(data);

return dst;
}

/*----------------------------
* 功能 : 获取图像的 CEDD 编码‚
*----------------------------
* 函数 : ceddCoder
* 访问 : public
* 返回 :
* 参数 : cv::Mat * src 输入图像
* 参数 : vector<float>& code 输出编码序列
*/
void CcsDll2cppDllTest::ceddCoder(cv::Mat *img, vector<float>& code)
{
CEDD_Descriptor::CEDD^ cedd = GetImpObj(m_pImp);
cli::array<double> ^arrCEDD;

System::Drawing::Bitmap^ bmpImg = encodeMatToImage(img);
arrCEDD = cedd->Apply(bmpImg);

int len = arrCEDD->GetLength(0);
code.resize(len);
for (int i=0;i<len;i++)
{
code[i] = (float)arrCEDD[i];
}
}


赵4老师 2012-06-19
  • 打赏
  • 举报
回复
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vccore/html/4299dfce-392f-4933-8bf0-5da2f0d1c282.htm
混合(本机和托管)程序集

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧