.net 调用 非托管C++的类

问题描述

背景:安装了一个开发包,通过开发包中的SaperaBasic类(很多类的统称)可以用C++或.net开发控制它们公司硬件的软件,SaperaBasic类包含两种类库:.net调用的和C++调用的(非托管),我需要使用.net开发(CLR,即C++.net),我选择的硬件是由一个叫SaperaRTPro类控制的,它是继承自SaperaBasic中的一两个类生成的,问题来了:因为我选的硬件不具有代表性,所以这个公司只提供了SaperaRTPro的C++类库(.h文件和DLL文件),我怎么在.net环境下,调用这个库?注:SaperaRTPro只提供了.h和SYSTEM32下安装的一些DLL,它的实现应该就是在这个DLL中,但这个DLL不是托管集,所以我在.net中不能通过引用直接调用。我会DLLIMPORT这种引用,但是我想调用整个类,不仅仅是用它的函数,这个局,怎么破?

解决方案

解决方案二:
?你不使用vc开发么?添加dll依赖,引用头文件啊。
解决方案三:
非托管的就用dllimport的方式而不是添加引用..另外调用类是什么概念?最终不都是调用类里面的方法么?
解决方案四:
托管程序不能直接访问C++类。用VC++.NET去访问,并且包装成.NET程序集。
解决方案五:
引用3楼caozhy的回复:

托管程序不能直接访问C++类。用VC++.NET去访问,并且包装成.NET程序集。

请问怎么把整个类包装成.net程序集?
解决方案六:
给你一个样例。//下列ifdef块是创建使从DLL导出更简单的//宏的标准方法。此DLL中的所有文件都是用命令行上定义的CFORCS_EXPORTS//符号编译的。在使用此DLL的//任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将//CFORCS_API函数视为是从DLL导入的,而此DLL则将用此宏定义的//符号视为是被导出的。#ifdefCFORCS_EXPORTS#defineCFORCS_API__declspec(dllexport)#else#defineCFORCS_API__declspec(dllimport)#endifstructREAD_DATA{intnLength;unsignedcharbtsData[256];};//此类是从AShura.CForCS.dll导出的classCFORCS_APICCForCS{public:CCForCS(void);CCForCS(intnValue);~CCForCS(void);public:voidPrint(LPCWSTRpszMessage);intGetValue(void);BSTRGetBSTR(intnIndex);BOOLReadData(void*pOut);intMemberValue;protected:virtualintVFunctionBefore(LPCWSTRpszMessage,int*pnValue);virtualvoidVFunctionAfter(LPCWSTRpszMessage,intnValue);private:int_nValue;};externCFORCS_APIintnCForCS;CFORCS_APIintfnCForCS(void);

//CForCS.cpp:定义DLL应用程序的导出函数。//#include"stdafx.h"#include"CForCS.h"//这是导出变量的一个示例CFORCS_APIintnCForCS=0;//这是导出函数的一个示例。CFORCS_APIintfnCForCS(void){AUTOTRACEX;return42;}//这是已导出类的构造函数。//有关类定义的信息,请参阅AShura.CForCS.hCCForCS::CCForCS():_nValue(0),MemberValue(0){AUTOTRACEX;}CCForCS::~CCForCS(){AUTOTRACEX;}CCForCS::CCForCS(intnValue):_nValue(nValue),MemberValue(nValue){AUTOTRACEX;}intCCForCS::GetValue(void){AUTOTRACEX;return_nValue+MemberValue;}BSTRCCForCS::GetBSTR(intnIndex){AUTOTRACEX;WCHARszNumber[32];swprintf_s(szNumber,_countof(szNumber),L"BSTRindex=%d.",nIndex);returnSysAllocString(szNumber);}BOOLCCForCS::ReadData(void*p){AUTOTRACEX;READ_DATArd[3];for(inti=0;i<3;++i){rd[i].nLength=(i+1)*10;for(intj=0;j<rd[i].nLength;++j){rd[i].btsData[j]=j;}}memcpy_s(p,sizeof(rd),&rd,sizeof(rd));returnTRUE;}voidCCForCS::Print(LPCWSTRpszMessage){AUTOTRACEX;intnValue=0x12345;intn=VFunctionBefore(pszMessage,&nValue);TR(L"message=%s,value=%d,CForCS=%d.",pszMessage,n,nValue);VFunctionAfter(pszMessage,nValue);}intCCForCS::VFunctionBefore(LPCWSTRpszMessage,int*pnValue){AUTOTRACEX;TR(L"Before:message=%s,value=%d,CForCS=%d.",pszMessage,_nValue,nCForCS);if(pnValue){*pnValue=nCForCS;}return_nValue;}voidCCForCS::VFunctionAfter(LPCWSTRpszMessage,intnValue){AUTOTRACEX;nCForCS=nValue;TR(L"After:message=%s,value=%d,CForCS=%d.",pszMessage,_nValue,nCForCS);}

解决方案七:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Runtime.InteropServices;namespaceAShura.CSForC{staticclassNativeImport{classDllImportedField{[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]privatestaticexternIntPtrLoadLibrary([In]stringlpFileName);[DllImport("Kernel32.dll")]privatestaticexternvoidFreeLibrary([In]IntPtrhModule);[DllImport("Kernel32.dll",CharSet=CharSet.Ansi)]privatestaticexternIntPtrGetProcAddress([In]IntPtrhModule,[In]stringlpProcName);privateIntPtrhModule;privateIntPtrptrAddress;publicDllImportedField(stringdllname,stringfieldname){hModule=LoadLibrary(dllname);ptrAddress=GetProcAddress(hModule,fieldname);}publicvoidDispose(){Dispose(true);GC.SuppressFinalize(this);}privatebooldisposed=false;protectedvirtualvoidDispose(booldisposing){if(!this.disposed){if(hModule!=IntPtr.Zero){FreeLibrary(hModule);}disposed=true;}}~DllImportedField(){Dispose(false);}publicTGetValue<T>(){return(T)Marshal.PtrToStructure(ptrAddress,typeof(T));}publicvoidSetValue<T>(Tvalue){Marshal.StructureToPtr(value,ptrAddress,false);}}privatestaticDllImportedField_nCForCS=newDllImportedField("..\..\..\Debug\CForCS.dll","?nCForCS@@3HA");publicstaticintnCForCS{get{return_nCForCS.GetValue<int>();}set{_nCForCS.SetValue(value);}}}classCVTable:IDisposable{IntPtr_vtable;publicCVTable(paramsDelegate[]methods){_vtable=Marshal.AllocHGlobal(methods.Length*Marshal.SizeOf(typeof(IntPtr)));for(inti=0;i<methods.Length;++i){Marshal.WriteIntPtr(_vtable,i*Marshal.SizeOf(typeof(IntPtr)),Marshal.GetFunctionPointerForDelegate(methods[i]));}}publicvoidDispose(){Dispose(true);GC.SuppressFinalize(this);}privatebooldisposed=false;protectedvirtualvoidDispose(booldisposing){if(!this.disposed){if(_vtable!=IntPtr.Zero){Marshal.FreeHGlobal(_vtable);_vtable=IntPtr.Zero;}disposed=true;}}~CVTable(){Dispose(false);}publicIntPtrCreateVTable(Object@this,IntPtrptrThis,intindex,intoffsetOfThis){IntPtrold=Marshal.ReadIntPtr(ptrThis,index*Marshal.SizeOf(typeof(IntPtr)));Marshal.WriteIntPtr(ptrThis,index*Marshal.SizeOf(typeof(IntPtr)),_vtable);Marshal.WriteIntPtr(ptrThis,offsetOfThis,GCHandle.ToIntPtr(GCHandle.Alloc(@this)));returnold;}publicvoidReleaseVTable(IntPtrptrThis,intindex,intoffsetOfThis,IntPtrvtable){if(ptrThis!=IntPtr.Zero){GCHandle.FromIntPtr(Marshal.ReadIntPtr(ptrThis,offsetOfThis)).Free();Marshal.WriteIntPtr(ptrThis,index*Marshal.SizeOf(typeof(IntPtr)),vtable);}}publicObjectGetThisObject(IntPtrptrThis,intoffsetOfThis){returnGCHandle.FromIntPtr(Marshal.ReadIntPtr(ptrThis,offsetOfThis)).Target;}}[StructLayout(LayoutKind.Sequential)]publicstruct_CForCS{privateIntPtr_vtable;publicint_MemberValue;privateint_nValue;}[StructLayout(LayoutKind.Sequential)]publicstruct_READ_DATA{publicintLength;[MarshalAs(UnmanagedType.ByValArray,SizeConst=256)]publicbyte[]Data;}[StructLayout(LayoutKind.Sequential)]publicstruct_READ_DATA_ARRAY{[MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]public_READ_DATA[]Data;}publicclassCForCS:IDisposable{privateconststringdllname="..\..\..\Debug\CForCS.dll";privatestaticint_BaseClassSize=Marshal.SizeOf(typeof(_CForCS));privateIntPtr_basecpp;privateIntPtr_basecppvtable;privatestaticCVTable_vtable=newCVTable(new_VFunctionBeforeHandler(_VFunctionBefore_),new_VFunctionAfterHandler(_VFunctionAfter_));[DllImport(dllname,EntryPoint="??0CCForCS@@QAE@XZ",CallingConvention=CallingConvention.ThisCall)]privatestaticexternvoid_Constructor([In]IntPtr@this);publicCForCS(){_basecpp=Marshal.AllocCoTaskMem(_BaseClassSize+Marshal.SizeOf(typeof(IntPtr)));_Constructor(_basecpp);_basecppvtable=_vtable.CreateVTable(this,_basecpp,0,_BaseClassSize);}[DllImport(dllname,EntryPoint="??0CCForCS@@QAE@H@Z",CallingConvention=CallingConvention.ThisCall)]privatestaticexternvoid_Constructor([In]IntPtr@this,[In,MarshalAs(UnmanagedType.I4)]intvalue);publicCForCS(intvalue){_basecpp=Marshal.AllocCoTaskMem(_BaseClassSize+Marshal.SizeOf(typeof(IntPtr)));_Constructor(_basecpp,value);_vtable.CreateVTable(this,_basecpp,0,_BaseClassSize);}publicvoidDispose(){Dispose(true);GC.SuppressFinalize(this);}privatebooldisposed=false;[DllImport(dllname,EntryPoint="??1CCForCS@@QAE@XZ",CallingConvention=CallingConvention.ThisCall)]privatestaticexternvoid_Destructor([In]IntPtr@this);protectedvirtualvoidDispose(booldisposing){if(!this.disposed){if(_basecpp!=IntPtr.Zero){_vtable.ReleaseVTable(_basecpp,0,_BaseClassSize,_basecppvtable);_Destructor(_basecpp);Marshal.FreeCoTaskMem(_basecpp);_basecpp=IntPtr.Zero;}disposed=true;}}~CForCS(){Dispose(false);}[DllImport(dllname,EntryPoint="?Print@CCForCS@@QAEXPB_W@Z",CallingConvention=CallingConvention.ThisCall)]privatestaticexternvoid_Print([In]IntPtr@this,[In,MarshalAs(UnmanagedType.LPWStr)]stringmessage);publicvoidPrint(stringmessage){_Print(_basecpp,message);}[DllImport(dllname,EntryPoint="?GetValue@CCForCS@@QAEHXZ",CallingConvention=CallingConvention.ThisCall)][return:MarshalAs(UnmanagedType.I4)]privatestaticexternint_GetValue([In]IntPtr@this);publicintGetValue(){return_GetValue(_basecpp);}publicintMemberValue{get{returnMarshal.ReadInt32(_basecpp,(int)Marshal.OffsetOf(typeof(_CForCS),"_MemberValue"));}set{Marshal.WriteInt32(_basecpp,(int)Marshal.OffsetOf(typeof(_CForCS),"_MemberValue"),value);}}[DllImport(dllname,EntryPoint="?GetBSTR@CCForCS@@QAEPA_WH@Z",CallingConvention=CallingConvention.ThisCall)][return:MarshalAs(UnmanagedType.BStr)]privatestaticexternstring_GetGetBSTR([In]IntPtr@this,[In,MarshalAs(UnmanagedType.I4)]intindex);publicstringGetString(intindex){return_GetGetBSTR(_basecpp,index);}[DllImport(dllname,EntryPoint="?ReadData@CCForCS@@QAEHPAX@Z",CallingConvention=CallingConvention.ThisCall)][return:MarshalAs(UnmanagedType.Bool)]privatestaticexternbool_ReadData([In]IntPtr@this,[In]IntPtrdata);publicbyte[][]Data{get{intSize=Marshal.SizeOf(typeof(_READ_DATA));IntPtrptrData=Marshal.AllocHGlobal(3*Size);if(_ReadData(_basecpp,ptrData)){byte[][]d=newbyte[3][];for(inti=0;i<d.Length;++i){vardata=(_READ_DATA)Marshal.PtrToStructure(ptrData+i*Size,typeof(_READ_DATA));d[i]=newbyte[data.Length];Array.Copy(data.Data,d[i],d[i].Length);}returnd;}thrownewException();}}[DllImport(dllname,EntryPoint="?VFunctionBefore@CCForCS@@MAEHPB_WPAH@Z",CallingConvention=CallingConvention.ThisCall)][return:MarshalAs(UnmanagedType.I4)]privatestaticexternint_VFunctionBefore([In]IntPtr@this,[In,MarshalAs(UnmanagedType.LPWStr)]stringmessage,[Out,MarshalAs(UnmanagedType.I4)]outintvalue);[UnmanagedFunctionPointer(CallingConvention.ThisCall)]privatedelegateint_VFunctionBeforeHandler([In]IntPtr@this,[In,MarshalAs(UnmanagedType.LPWStr)]stringmessage,[Out,MarshalAs(UnmanagedType.I4)]outintvalue);privatestaticint_VFunctionBefore_([In]IntPtr@this,stringmessage,outintvalue){return((CForCS)_vtable.GetThisObject(@this,_BaseClassSize)).VFunctionBefore(message,outvalue);}protectedvirtualintVFunctionBefore(stringmessage,outintvalue){return_VFunctionBefore(_basecpp,message,outvalue);}[DllImport(dllname,EntryPoint="?VFunctionAfter@CCForCS@@MAEXPB_WH@Z",CallingConvention=CallingConvention.ThisCall)]privatestaticexternvoid_VFunctionAfter([In]IntPtr@this,[In,MarshalAs(UnmanagedType.LPWStr)]stringmessage,[In,MarshalAs(UnmanagedType.I4)]intvalue);[UnmanagedFunctionPointer(CallingConvention.ThisCall)]privatedelegatevoid_VFunctionAfterHandler([In]IntPtr@this,[In,MarshalAs(UnmanagedType.LPWStr)]stringmessage,[In,MarshalAs(UnmanagedType.I4)]intvalue);privatestaticvoid_VFunctionAfter_([In]IntPtr@this,stringmessage,intvalue){((CForCS)_vtable.GetThisObject(@this,_BaseClassSize)).VFunctionAfter(message,value);}protectedvirtualvoidVFunctionAfter(stringmessage,intvalue){_VFunctionAfter(_basecpp,message,value);}}classCSForC:CForCS{publicCSForC(){}publicCSForC(intvalue):base(value){}protectedoverrideintVFunctionBefore(stringmessage,outintvalue){intn=base.VFunctionBefore(message,outvalue);value=100;returnn;}protectedoverridevoidVFunctionAfter(stringmessage,intvalue){System.Diagnostics.Debug.WriteLine(string.Format("{0},{1}.",message,value));}}}

解决方案八:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceAShura.CSForC{classProgram{staticvoidMain(string[]args){varv=newCSForC(123456789);v.Print("CSMessage");intvalue=v.GetValue();System.Diagnostics.Debug.WriteLine(string.Format("GetValue()={0}",value));intstaticValue=NativeImport.nCForCS;System.Diagnostics.Debug.WriteLine(string.Format("StaticValue={0}",staticValue));NativeImport.nCForCS=987654321;staticValue=NativeImport.nCForCS;System.Diagnostics.Debug.WriteLine(string.Format("StaticValue={0}",staticValue));stringstringValue=v.GetString(1);System.Diagnostics.Debug.WriteLine(string.Format("StringValue()={0}",stringValue));stringValue=v.GetString(2);System.Diagnostics.Debug.WriteLine(string.Format("StringValue()={0}",stringValue));intmemberValue=v.MemberValue;System.Diagnostics.Debug.WriteLine(string.Format("MemberValue={0}",memberValue));v.MemberValue=111111111;memberValue=v.MemberValue;System.Diagnostics.Debug.WriteLine(string.Format("MemberValue={0}",memberValue));byte[][]data=v.Data;for(inti=0;i<data.Length;++i){if(data[i]!=null){for(intj=0;j<data[i].Length;++j){System.Diagnostics.Debug.Write(string.Format("{0},",data[i][j]));}System.Diagnostics.Debug.WriteLine("");}}((IDisposable)v).Dispose();}}}

解决方案九:
1、分析一下是不是一定需要这个类,能不用就不用了。2、你这个需求我认为,用clr把非托管的dll封装为.net的类库是最好的。
解决方案十:
引用8楼yinshi2006的回复:

1、分析一下是不是一定需要这个类,能不用就不用了。2、你这个需求我认为,用clr把非托管的dll封装为.net的类库是最好的。

你说的方法确实是比较靠谱的,把非托管的DLL封装为.net程序集,但是怎么封装啊?我没有这个DLL的源码
解决方案十一:
不需要得到dll源码。像普通c++程序使用dll就行。我再其他帖子里的回帖============================新建工程》visualc++》CLR》类库,语法什么的自己琢磨吧,基于C++扩展了c#里的概念,比如多了gcnew(对应C#里的new,clr里的new还是c的new)和%(用在变量声明,对应C#里的引用)等。=============================================封装出的类库,和用c#写的类库一样使用因为clr的语法说明中文的不多,熟悉一下需要4、5天。如果你英文不错,绝对可以更快。我十分推荐这样做,用它封装过sqlite,这样除了dll,稳定性和可靠性尽在掌握。

时间: 2024-08-01 11:49:54

.net 调用 非托管C++的类的相关文章

关于c#动态调用非托管DLL的内存释放问题

问题描述 本人由于客户的需要,需要在程序的运行过程中,动态加载不同的DLL.这与直接调用非托管DLL不一样.下面这个帖子中的第三个方法很好的说明了如何动态调用非托管DLL.http://blog.csdn.net/pansiom/article/details/568096#comments为了方便使用,我把文中的方法弄成了一个DLDApi类,如下usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Re

在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解) 背景

背景       在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件的时候,通过C#来开发应用软件时,就需要利用DllImport特性进行方法调用.本篇文章将引导你快速理解这个调用的过程.   步骤 1. 创建一个CSharpInvokeCPP的解决方案:   2. 创建一个C++的动态库项目:   3. 在应用程序设置中,选择"DLL",其他按照默认选项: 最后点击完成,得到如图所示项目:       我们可以看到这里有一些文件,其中dllmain.c

.net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃?

问题描述 .net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃? 有一个.net服务,服务中开了多线程.其中有一线程会去调用非托管C++DLL,并阻塞等待其返回值.其他线程同步做文件处理.数据状态更新等操作.现在调用非托管C++DLL的线程会因为非托管代码的问题,崩溃.这样整个服务也就崩溃了!需要人工去服务器上重启该服务!请问:如何防止整个服务崩溃?是否可以捕获非托管C++中的错误.因为已经try catch了,但什么都捕获不到,直接服务崩溃! 解决方案 这个应该要想办法解决C++

非托管dll-C#调用非托管DLL,报“其他内存已损坏”,请问怎么解决呢?

问题描述 C#调用非托管DLL,报"其他内存已损坏",请问怎么解决呢? 定义: [DllImport("BSEncrypt.dll")] public static extern bool MD5String(ref string instr, int inlen, ref string outstr, int outlen); 调用: String ls_MD5Password = new String('', 100); string as_Password =

C#调用非托管C++DLL中的函数接口

问题描述 C#调用非托管C++DLL中的函数接口(有生成的DLL文件和Lib文件)怎么引用?引用项添加不了 解决方案 解决方案二:使用DllImport,添加引用只能针对.NET控件或COM组件.解决方案三:DllImport具体搜p/Invokehttp://www.cnblogs.com/xuqiang/archive/2010/12/21/1953355.html解决方案四:C++DLL中的函数中还调用了openCV的函数,能说一下怎么整么?解决方案五:引用3楼qq_28744297的回复

C#调用非托管的代码

using System; using System.Runtime.InteropServices; namespace 调用非托管项目demo { class Program { static void Main(string[] args) { Win32.MessageBox(0, "Hello I am Kun", "stm32", 0); } public class Win32 { [DllImport("user32.dll",

调用非托管dll常出现的bug及解决办法

C和C++有很多好的类库的沉淀,在.NET中,完全抛弃它们而重头再来是非常不明智的.也是不现实的,所以,我们经常需要通过Pinvoke来使用以前遗留下来的非托管的dll.就.NET中使用非托管的dll经验而言,经常碰到的问题至少有两个,它们都是通过在运行时抛出异常来体现的. 1.试图加载格式不正确的程序 出现这种异常,通常是.NET应用程序的"目标平台"与非托管dll的平台不一样. 一般,在使用VS开发.NET的应用程序和类库时,默认的目标平台为"Any CPU",

C#使用DllImport调用非托管的代码的方法_C#教程

找到GetShortPathName的方法签名, DWORD GetShortPathName(LPCTSTR tpszLongPath,TPTSTR lpszShortPath,DWORD cchBuffer): 非托管及托管数据类型对应关系: LPCTSTR         String LPTSTR           StringBuilder DWORD          int DllImport的导入规则: 1.方法名与Win API完全一样.如果在C#中调用时显示完全不同的方法名

C#调用非托管DLL,窗口关闭后报错,求教!

问题描述 这几天在做一个医院的报销接口系统,对方提供的接口是一个DLL动态库,暂且叫做A.DLL,是delphi的.其中A.DLL中封装的各功能方法,我都能正常调用,也都执行正常,但是唯一一点不足的就是,有的时候我关闭浏览器(我们的系统是BS)的时候,就会弹出下面的那个错误提示:无效的窗口句柄.以前做此类报销接口的时候其他厂商也很多是非托管DLL,但是没有出现过此类情况.百度了很长时间,有的说资源释放问题,有的说是A.DLL自身没有做好处理,各种各样的方案吧.然后自己又写了一个CS的Demo来测