https://www.cnblogs.com/xuqp/p/11987707.html
目录:
1.非托管方式
2.托管方式
3.介绍 extern "C"
4.介绍 DllImport
1.非托管方式
第一种,非托管方式:调用类和方法https://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
非托管方式,只能调用函数,并且函数在extern "C"的体里面
有一下几种方式,把函数都写了,把接口写了。
//创建对象的方法
extern "C" EXAMPLEUNMANAGEDDLL_API CUnmanagedTestClass* CreateTestClass()
{
return new CUnmanagedTestClass();
}
//释放对象
extern "C" EXAMPLEUNMANAGEDDLL_API void DisposeTestClass(CUnmanagedTestClass* pObject)
{
if(pObject != NULL)
{
delete pObject;
pObject = NULL;
}
}
//调用函数
extern "C" EXAMPLEUNMANAGEDDLL_API void CallPassInt(CUnmanagedTestClass* pObject, int nValue)
{
if(pObject != NULL)
{
pObject->PassInt(nValue);
}
}
//调用函数
extern "C" EXAMPLEUNMANAGEDDLL_API void CallPassString(CUnmanagedTestClass* pObject, char* pchValue);
extern "C"{
EXAMPLEUNMANAGEDDLL_API char* CallReturnString(CUnmanagedTestClass* pObject)
}
C++的调用
把生成的TestClassDLL.dll放到 bin/Debug/下,然后在C#中调用
public class CSUnmanagedTestClass : IDisposable
{
#region PInvokes
[DllImport("TestClassDLL.dll")]
static private extern IntPtr CreateTestClass();
[DllImport("TestClassDLL.dll")]
static private extern void DisposeTestClass(IntPtr pTestClassObject);
[DllImport("TestClassDLL.dll")]
static private extern void CallPassInt(IntPtr pTestClassObject, int nValue);
.
.
.
#endregion PInvokes
#region Members
private IntPtr m_pNativeObject;
// Variable to hold the C++ class's this pointer
#endregion Members
public CSUnmanagedTestClass()
{
// We have to Create an instance of this class through an exported
// function
this.m_pNativeObject = CreateTestClass();
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool bDisposing)
{
if(this.m_pNativeObject != IntPtr.Zero)
{
// Call the DLL Export to dispose this class
DisposeTestClass(this.m_pNativeObject);
this.m_pNativeObject = IntPtr.Zero;
}
if(bDisposing)
{
// No need to call the finalizer since we've now cleaned
// up the unmanaged memory
GC.SuppressFinalize(this);
}
}
// This finalizer is called when Garbage collection occurs, but only if
// the IDisposable.Dispose method wasn't already called.
~CSUnmanagedTestClass()
{
Dispose(false);
}
#region Wrapper methods
public void PassInt(int nValue)
{
CallPassInt(this.m_pNativeObject, nValue);
}
.
.
.
#endregion Wrapper methods
}
2.托管方式
我手上有一个C++写的类(NativeClass),想在C#下调用这个类,可是C#是没有简单的像Dllimport这样的方法获取非托管C++ dll里的类。我的解决方法是,生成一个托管C++的dll,然后在C#下引用这个dll。因为托管代码与非托管代码是不能在一个文件里混编的,所以我必须将非托管C++写的NativeClass用托管C++的手段封装一下,然后生成一个dll,以供C#调用。
https://www.cnblogs.com/stemon/p/4246165.html
3.介绍 extern "C"
:https://www.cnblogs.com/xiangtingshen/p/10980055.html
extern "C"包含双重含义,
- 被extern "C"修饰的变量和函数是按照C语言方式进行编译和链接的:这点很重要!!!!
-
extern "C"的使用要点总结
1,可以是如下的单一语句:
extern "C" double sqrt(double);
2,可以是复合语句, 相当于复合语句中的声明都加了extern "C"
extern "C" { double sqrt(double); int min(int, int); }3,可以包含头文件,相当于头文件中的声明都加了extern "C"
|
1
2
3
4
|
extern "C"{ #include <cmath>} |
4.介绍 DllImport
https://www.cnblogs.com/fer-team/archive/2017/12/13/8033413.html
要使用DllImport需要引用命名空间: System.Runtime.InteropServices;
DllImport 属性定义
如下:
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName){...} //定位参数为dllName
public CallingConvention CallingConvention; //入口点调用约定
public CharSet CharSet; //入口点采用的字符接
public string EntryPoint; //入口点名称
public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false
public bool PreserveSig; //方法的签名是被保留还是被转换
public bool SetLastError; //FindLastError方法的返回值保存在这里
public string Value {get {...}}
}
}
说明:
1、DllImport只能放置在方法声明上。
2、DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。
3、DllImport具有五个命名参数:
a、CallingConvention 参数指示入口点的调用约定。如果未指定CallingConvention,则使用默认值CallingConvention.Winapi。
b、CharSet参数指定用在入口点的字符集。如果未指定CharSet,则使用默认值CharSet.Auto。
c、EntryPoint参数给出dll中入口点的名称。如果未指定EntryPoint,则使用方法本身的名称。
d、ExactSpelling参数指示EntryPoint是否必须与指示的入口点的拼写完全匹配。如果未指定ExactSpelling,则使用默认值false。
e、PreserveSig参数指示方法的签名被保留还是被转换。当签名被转换时,它被转换为一个具有HRESULT返回值和该返回值的一个名为retval的附加输出参数的签名。如果未指定PreserveSig,则使用默认值true。
f、SetLastError参数指示方法是否保留Win32“上一错误”。如果未指定SetLastError,则使用默认值false。
4、它是一次性属性类。
5、用DllImport属性修饰的方法必须具有extern修饰符。
python windows 环境变量
Check server headers and verify HTTP Status Codes
Where are the AES 256bit cipher suites? Please someone help
outlook 如何预订会议和会议室
安装Axis2的eclipse插件后,未出现界面
windows 环境变量
python 时间日期处理汇集
openldap学习笔记(使用openldap2.3.32)
set p4 environment in windows
