公司要用一个Canon数码相机的控件,封装CDSDK的功能。以前没做过类似的程序,CDSDK的文档只是写了C++的API。
开发过程中出现不少问题,至于详细的C#、C++程序设计不想说了。总结如下:
一、无法加载Dll文件问题场景:VC++编译过的dll类库,无法在C#通过DllImport属性调用。
错误: 无法在C#项目中使用Dll。
网上搜了不少文章帖子,解决方案有:
1 在项目中添加Dll引用,把Dll放到项目的bin目录下,添加引用,但是出现了:“未能添加引用的错误……这不是有效的com组件”等等的错误提示;可能原因:Dll只是普通的Win32动态库,不是Com组件,只能拷到项目目录中、不能添加引用。
2 在[DllImprot("")]使用绝对路径,如:[DllImport(@"D:\fenci.dll")],试了试有时可行(郁闷),但是扩展性不高,不能修改文件路径。
3 添加引用,在C#中添加“using dll文件名称;”。
其他方法:1.与应用程序放在同一目录下 2.系统目录下 3.设置系统变量 4.以配置文件的方式给出dll路径,程序中读取 5.用regsvr32 重新注册该组件
我的解决办法:1. 将编译好的Dll文件复制到项目的“bin\debug”目录下,此目录为我的项目生成路径;
2. 包含Dll文件到项目中;
3. 使用DllImport属性即可:
[DllImport("Canon.dll", EntryPoint = "#38")] private static extern ErrorID takeAPicture([MarshalAs(UnmanagedType.LPStr)] string filePath);
二、无法找到程序入口点终于可以调用Dll类库了,新的问题也出现了:“未处理的异常: System.EntryPointNotFoundException: 无法在 DLL *.dll 中找到名为 ***的入口点。”。
找资料…
分析原因如下:C++到处函数有两种调用方式:序号、函数名,如[DllImport("Canon.dll", EntryPoint = "#38")]和[DllImport("Canon.dll", EntryPoint = "BeginEnumerateFormatAttribute")],序号好像要通过.def文件使序号和函数对应,对C++不熟改用第二种方式,至于DllImport属性的参数自己找好了,而编译好的Dll中的函数名称是类如“?
BeginEnumerateFormatAttribute@@AAU” 而不是要用的“BeginEnumerateFormatAttribute”。
解决:
extern "C" __declspec(dllexport) long BeginEnumerateFormatAttribute();long BeginEnumerateFormatAttribute()
{
return checkResult(CDEnumImageFormatAttributeReset(deviceHandle, & enumerateFormatAttributeHandle));
}
加上extern "C" 即可。
--
由 Jin King 于 12/11/2007 02:05:00 下午 在
asynchronous loving 上发表