今天在项目中看到C:\WINDOWS\Microsoft.NET\Framework\v...\REGASM.exe /regfile:xxx.reg xxx.dll,注册COM组件。
开始不明白为啥要注册COM组件,c#自己调自己的dll用不着这样啊,网上查看大都是讲如何注册COM组件。
经过不懈网上游荡,原来注册COM组件是给其他语言调用的,因为c#程序是托管代码,所以和其他非托管代码有所差异。
查就查到底,继续在网上查资料,把这块东西系统的整理下:
1.c#引用托管程序集-----直接引用
2.c#引用非托管代码-----通过P/Invoke(Plateform Invoke)机制调用dll函数
IntPtr相当于指针,通过Marshal类操作非托管内存
C代码和C++代码编译方式不同,C语言编译出来的函数入口和函数名一样,但C++编译出来的入口和函数名不一样,这是因为有重载的关系;这时,如果是C++代码,要么在函数名前加extern "C" rvalue function(param...),要么在编译出来的dll用dumpbin类似工具反编译出来函数入口EntryPoint
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
动态调用
public static class NativeMethod
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern int LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
public static extern IntPtr GetProcAddress(int hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
public static extern bool FreeLibrary(int hModule);
}
static void Main(string[] args)
{
//1.load c++ dll
int hModule = NativeMethod.LoadLibrary(@"c:/CppDemo.dll");
if (hModule == 0)
return;
IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "MyDelegate");
MyDelegate myDele = (MyDelegate)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MyDelegate));
Console.WriteLine(myDele(1,2));
}
///
/// 函数指针
///
///
///
///
delegate int MyDelegate(int a, int b);
3. clr c++调用c#dll
设置项目属性-->配置属性-->常规-->公共语言运行时支持-->公共语言运行时支持(clr)
#using "../debug/xx.dll"
using namespace xxx;
然后按照托管c++/clr的语法:托管对象使用^……
4.非托管c++调用c#dll
1)用c#写dll
写接口和实现类,贴上GUID特性标签(工具->创建GUID->选择5->复制),Properties下的AssemblyInfo.cs中ComVisible为true
2)注册dll为COM组件
如果在本机开发,在属性->生成->为COM互操作注册即能完成注册功能或应用程序->程序集信息
但是要在别的机子上使用那就需要用REGASM.exe来注册
C:\WINDOWS\Microsoft.NET\Framework\v...\REGASM.exe /regfile:xxx.reg xxx.dll然后运行xxx.reg注册该COM组件
3)使用
namespace ComInteropDemo
{
//接口声明
[Guid("7103C10A-2072-49fc-AD61-475BEE1C5FBB")]
public interface ComInteropInterface
{
[DispId(1)]
int Add(int a, int b);
[DispId(2)]
int Minus(int a, int b);
}
//对于实现类的声明
[Guid("87796E96-EC28-4570-90C3-A395F4F4A7D6")]
[ClassInterface(ClassInterfaceType.None)]
public class ComInterop : ServicedComponent, ComInteropInterface
{
public ComInterop() { }
public int Add(int a, int b)
{
return a + b;
}
public int Minus(int a, int b)
{
return a - b;
}
}
}
#include "stdafx.h"
#include
using namespace std;
#import "..//Debug//ComInteropDemo.tlb"
//路径一定要正确
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
//ComInteropDemo::ComInterop *p;
CoInitialize ( NULL );
//创建智能指针ComInteropDemo::ComInteropInterface
ComInteropDemo::ComInteropInterfacePtr ptr;
//创建实例
hr = ptr.CreateInstance(__uuidof (ComInteropDemo::ComInterop));
if(hr == S_OK)
{
cout << ptr->Add (1.0, 2.0);
}
CoUninitialize ();
return 0;
}