2008年(787)
分类:
2008-09-25 16:08:39
最近几天一直在玩 C#,
C# 的类型检查非常严格, 或许一直在研究 C++ 的 DLL 如何被 C# 调用吧, 所以感觉 C# 的方便性还是没体现出来.
在编写 DLL 的时候,只要你不是 managed c++ 代码, 都必须遵循标准 DLL 输出方式, 也就是
extern "C" __declspec(dllexport)
在几天的代码中, vc 编译选项使用 /CLR 的话, C++ 代码写为 public class xxx, 就可以实例化一个 class 对象出来, 也可以认出 namespace, 问题就是, 无法通过 object 绑定一个函数.于是我使用了标准的 C 函数方式输出 DLL.
使用这样的方式是没有任何的问题, 就算你在C++代码中有 namespace 也可以不用去管, 因为这是编译期的事情.
在使用之前, 你必须用 C# 这么包装一层
public class MyClass
{
[DllImport("my_dll.dll", EntryPoint = "my_func", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern int my_func(char* s, Int32 sz); // 这里就可以参考 my_func 原型
};
注意,如果你用 char*, 必须使用 unsafe 关键字.
由于是 static 函数的关系, 所以直接 MyClass.my_func("xxx", 123); 就可以.
关于 string 类型, 那是 C# 和 C++ 之间最让我头疼的问题.
C# 的每一个 string 貌似都不含二进制, 而且使用 C++ 的 char* 必须使用 unsafe, 而你如果要写 BinaryWrite 类的话, 写出来的 char[] 数组居然是 unicode 的.
标准是国际标准了,就是类型实在要求太严格了.
要从 string 转化为 char* 必须使用 IntPtr ptr = Marshal.StringToHGlobalAnsi(xxx, size);
然后 void* p = ptr.ToPointer();
然后 (char*)p;
囧rz.... 太令人震撼了...
或许刚开始研究 C# 吧, 不是怎么懂, 可能 C# 还是挺方便的...