1、C#调用非托管代码的方式:
2、DllImport方法调用
1)导入规则:
i.方法名与Win API完全一样,设置EntryPoint属性,可以在c#中显示不同的方法名称;
ii.函数除了需要DllImport类修饰符外,还需要声明public static extern类型;
iii.函数返回值和参数必须和调用的API的完全一样;
iv.必须引入System,Runtime.InteropServices命名空间;
注:DLL的路径如果没有写,DllImport会按照以下三种顺序查找DLL:①exe所在的目 录;②system32目录;③环境变量目录;
2)DLLImport的可选属性:
i.EmtryPoint:可对方法采用不同的名称,使用别名
ii.CharSet:函数调用使用Unicode还是ANSI
iii.ExactSpelling:False,表示让编译器自己选择使用Unicode还是ANSI
iv.CallingConvention:它的参数只是入口点调用的约定;默认为CallingConvention.WinAPI;
v.PreserveSig: 指示方法签名应当被保留还是被转换,当被转换时它被转换为一个具有HRESULT返回值和该返回值的一个名为retral的附加输出参数的签名,默认为true
vi.SetLastError:指定是否保留上一次错误,默认为false;
Eg:
[DllImport(DllName,CharSet=CharSet.Auto,
EntryPoint="GetShort",
CallingConvention = CallingConvention.StdCall)]
public static extern int GetShortPathName();
sss
3、平台调用的原理
1)平台调用依赖于元数据在运行时查找导出的函数并封送其参数;
2)“平台调用”调用非托管函数时,它将依次执行以下操作:
i.查找包含该函数的DLL
ii.将DLL加载到内存中
iii.查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据
iv.将控制权转移给非托管函数
(注:只在第一次调用函数时,才会查找和加载DLL并查找函数在内存中的地址)