社区
C++ 语言
帖子详情
如何在非托管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错误。求教解决方案!
...全文
207
2
打赏
收藏
如何在非托管C++项目中引用c# dll
求教C# dll在非托管C++中的应用:目前试了两种方法,一是在项目中对引用C# dll的cpp文件开启/clr和创建对应的sydafx.h,但编译出现各种error;二是用托管C++将C# dll二次封装,在非托管项目中引用封装好的dll,编译没有问题,但是加载不了dll,启动程序出现0x000000c5错误。求教解决方案!
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用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
混合(本机和托管)程序集
非
托管
C++
调用
C#
的
dll
然而,CLR VIA
C#
提供了一种
非
托管
C++
直接调用的方法,该方法可以在
非
托管
代码
中
手动启动CLR加载应用程序域来运行
托管
的
dll
,从而调用其
中
的方法。 知识点1:
C++
调用
C#
编写的
dll
的必要性 在实际开发
中
,
C++
和
C#
是...
非
托管
C++
调用
C#
Dll
这个例子展示了
非
托管
C++
如何通过P/Invoke调用
C#
DLL
中
的函数。请注意,跨语言调用可能涉及类型转换、内存管理和线程同步等问题,需要仔细处理以确保正确性和性能。在实际
项目
中
,可能还需要考虑平台兼容性、异常...
C#
使用CLR调用
C++
的
DLL
库
然后,创建
托管
C++
类,这些类封装了
C++
DLL
中
的
非
托管
代码,并提供给
C#
应用程序调用的接口。 3. **创建
C#
EXE应用** - 最后,创建一个
C#
控制台应用程序
项目
。在
C#
代码
中
,添加对
C++
CLR类库的
引用
。然后,你可以像...
C++
调用
C#
的
DLL
实例程序
3. 在
C++
/CLI
中
引用
C#
DLL
:在
C++
/CLI
项目
中
,添加对
C#
DLL
的
引用
。这使得
C++
/CLI代码能够访问
C#
的类型和方法。 4. 使用
C++
/CLI调用
C#
方法:在
C++
/CLI代码
中
,引入
C#
命名空间,并创建对
C#
类的实例。然后,你可以像...
c++
动态加载
c#
编写生成的
dll
代码
综上所述,
C++
加载
C#
DLL
涉及的关键技术包括P/Invoke、数据类型转换、函数指针以及对.NET与
非
托管
环境差异的理解。正确地实现这一过程,可以充分利用
C#
的高级特性和
C++
的性能优势,构建跨语言的高效应用。
C++ 语言
65,187
社区成员
250,526
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章