VB调用VC++的DLL问题:1.无法返回参数,2.找不到入口点
2012-05-08 16:50
483 查看
最近忙于毕业论文的实验,主要用VS2010+openCV做图像处理,做了大量工作,遇到无数的问题。
首先就先说说今天遇到的问题吧:我想利用VB中读取的图像路径传入VC++,之前有的办法一直是将VB的字符串tempPath转换成Byte数组之后传入C++。如:
Dim sbyt() As Byte
ReDim sbyt(tempPath.Length - 1)
Dim sl() As Byte
sl = System.Text.Encoding.Default.GetBytes(tempPath)
For i As Integer = 0 To tempPath.Length - 1
sbyt(i) = sl(i)
Next
但是想实现一种直接传入的手段。
google……
发现VC++中接口参数可以是void tt(char *s)。于是乎写好该DLL。在VB中Public Declare Function tt Lib "*****.dll" (ByVal s As String)。结果报错,大意是无法返回参数。再google……最后终于在一篇english里面发现,原来我在VC++中定义的函数是void类型,没有返回值,但是我在VB中声明是用了function,所以改成sub!!
……
还是报错:无法在我指定的DLL中找到名为tt的函数入口点。
google……漫长时间地……
终于在http://www.newsmth.net/bbsanc.php?path=%2Fgroups%2Fcomp.faq%2FVisualBasic%2FCatalog%2F5%2FM.963616351.A里发现VC++允许不编写.def文件,而是在函数定义前加_declspec(dllexport)修饰符,这样的函数也可以被外部程序调用。
更新的错误出现:__declspec(dllexport) cannot be applied to a function
with the __clrcall
calling convention。。。。。。。。
原来我的VC++的DLL使用了managed类。文章http://social.msdn.microsoft.com/Forums/da/vclanguage/thread/bda0a91d-9be9-424b-954b-b80b2ab2dda5中给出了五条建议:
1) "don't use managed
parameters":
The whole point of my post is that I have functions in my non-managed class which have to deal with managed parameters. Clearly if I have
a function converting a System::String * to a std::string, I must use managed parameters.
2) "change it to a managed class":
I could be wrong, and I will try it out, but I am almost sure that when using Managed C++ a managed class can not refer to a C++ template
type in any way. Perhaps under VC++ 2005 when using C++/CLI a managed class can refer to a C++ template type but I am working in Managed C++ at least initially to port my code from VC++ 2003 to VC++ 2005..
3) "There
is nothing stopping you from using unmanaged parameters and doing converstion though since you can have managed local variables in an unmanaged method":
Since a function is converting from a managed variable ( System::String * ) to an unmanaged return value ( std::string ) there is no way to not pass a managed pointer.
4) "Another
suggestion is to not have it as a class but just as a set of functions.":
This may work since I am really just trying to export functions, which I have put in a class and made static functions of that class. However I would really expect the same problem since if the function uses a managed type, what prevents the compiler from calling
that function with the __clrcall calling convention and thus generating the same error ?
5) "The
final suggestion is to use this as a static library instead of a dynamic library.":
.NET assemblies are never static libraries. If you are telling me to use a plain C++ static library I do not think this can be done when my code refers to .NET types but maybe I am wrong about that.
没办法,因为图像处理往往需要占用大量内存,我觉得自己还是要用managed类,但是用managed类的参数是肯定无法在非managed的类中引用这个函数的(第3条建议)。于是我在原来DLL的命名空间里新建了一个un
managed类,使用__declspec(dllexport)声明tt函数:
__declspec(dllexport)
void tt(char *s);
还是不行。。。。尽管刚才已经看见过解决办法,但是我却没试出来——http://wenku.baidu.com/view/9f6666492e3f5727a5e96250.html
完美方案。。在__declspec(dllexport) 之前使用extern ”C“。。呵呵。原来如此。。不过要指出的是我一直无法在后来新建的那个un
managed类里面声明
extern
”C“__declspec(dllexport) void tt(char *s);
没办法,干脆直接在命名空间里声明了改函数。。不过这也符合第4条建议。
不管怎么说终于解决了问题,呵呵。。尽管自己不是软件出身,但是毕竟又增长了不少见识和知识。。仓促些,但还是记下来吧。。希望有所裨益!!
首先就先说说今天遇到的问题吧:我想利用VB中读取的图像路径传入VC++,之前有的办法一直是将VB的字符串tempPath转换成Byte数组之后传入C++。如:
Dim sbyt() As Byte
ReDim sbyt(tempPath.Length - 1)
Dim sl() As Byte
sl = System.Text.Encoding.Default.GetBytes(tempPath)
For i As Integer = 0 To tempPath.Length - 1
sbyt(i) = sl(i)
Next
但是想实现一种直接传入的手段。
google……
发现VC++中接口参数可以是void tt(char *s)。于是乎写好该DLL。在VB中Public Declare Function tt Lib "*****.dll" (ByVal s As String)。结果报错,大意是无法返回参数。再google……最后终于在一篇english里面发现,原来我在VC++中定义的函数是void类型,没有返回值,但是我在VB中声明是用了function,所以改成sub!!
……
还是报错:无法在我指定的DLL中找到名为tt的函数入口点。
google……漫长时间地……
终于在http://www.newsmth.net/bbsanc.php?path=%2Fgroups%2Fcomp.faq%2FVisualBasic%2FCatalog%2F5%2FM.963616351.A里发现VC++允许不编写.def文件,而是在函数定义前加_declspec(dllexport)修饰符,这样的函数也可以被外部程序调用。
更新的错误出现:__declspec(dllexport) cannot be applied to a function
with the __clrcall
calling convention。。。。。。。。
原来我的VC++的DLL使用了managed类。文章http://social.msdn.microsoft.com/Forums/da/vclanguage/thread/bda0a91d-9be9-424b-954b-b80b2ab2dda5中给出了五条建议:
1) "don't use managed
parameters":
The whole point of my post is that I have functions in my non-managed class which have to deal with managed parameters. Clearly if I have
a function converting a System::String * to a std::string, I must use managed parameters.
2) "change it to a managed class":
I could be wrong, and I will try it out, but I am almost sure that when using Managed C++ a managed class can not refer to a C++ template
type in any way. Perhaps under VC++ 2005 when using C++/CLI a managed class can refer to a C++ template type but I am working in Managed C++ at least initially to port my code from VC++ 2003 to VC++ 2005..
3) "There
is nothing stopping you from using unmanaged parameters and doing converstion though since you can have managed local variables in an unmanaged method":
Since a function is converting from a managed variable ( System::String * ) to an unmanaged return value ( std::string ) there is no way to not pass a managed pointer.
4) "Another
suggestion is to not have it as a class but just as a set of functions.":
This may work since I am really just trying to export functions, which I have put in a class and made static functions of that class. However I would really expect the same problem since if the function uses a managed type, what prevents the compiler from calling
that function with the __clrcall calling convention and thus generating the same error ?
5) "The
final suggestion is to use this as a static library instead of a dynamic library.":
.NET assemblies are never static libraries. If you are telling me to use a plain C++ static library I do not think this can be done when my code refers to .NET types but maybe I am wrong about that.
没办法,因为图像处理往往需要占用大量内存,我觉得自己还是要用managed类,但是用managed类的参数是肯定无法在非managed的类中引用这个函数的(第3条建议)。于是我在原来DLL的命名空间里新建了一个un
managed类,使用__declspec(dllexport)声明tt函数:
__declspec(dllexport)
void tt(char *s);
还是不行。。。。尽管刚才已经看见过解决办法,但是我却没试出来——http://wenku.baidu.com/view/9f6666492e3f5727a5e96250.html
完美方案。。在__declspec(dllexport) 之前使用extern ”C“。。呵呵。原来如此。。不过要指出的是我一直无法在后来新建的那个un
managed类里面声明
extern
”C“__declspec(dllexport) void tt(char *s);
没办法,干脆直接在命名空间里声明了改函数。。不过这也符合第4条建议。
不管怎么说终于解决了问题,呵呵。。尽管自己不是软件出身,但是毕竟又增长了不少见识和知识。。仓促些,但还是记下来吧。。希望有所裨益!!
相关文章推荐
- VB调用VC DLL的参数问题
- VB调用VC++的DLL问题:原因可能是托管的PInvoke 签名与非托管的目标签名不匹配。请检查PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
- (原创)VB调用DLL(VC)使用结构体参数时的内存对齐及分配的问题.
- VB调用VC dll的返回
- 提问:关于动态编译WebService为dll然后调用WebService的问题,无法返回xml文本
- matlab2012生成的dll调用出现无法初始化,libmx.dll找不到等问题
- c#的调用VC的dll输出参数的问题
- vb调用vc dll返回字符串类型
- 探讨:关于动态编译WebService为dll然后调用WebService的问题,无法返回xml文本
- VB调用VC dll的返回方式
- C#调用C++下Win32DLL,找不到入口问题,感谢TallMan
- 关于delphi调用vc编写的dll中参数类型有关问题
- c#调用C++的DLL找不到入口点以及衍生的相关问题
- VB调用C DLL时的参数传递问题
- C# 要调用VC++ DLL时参数问题请看这个
- 请问Delphi调用VC写的dll,有传入和传出参数都是unsigned char*运行中有有关问题
- java调用vc++ dll时无法加载的问题
- VB调用VC dll的返回方式
- VB调用C# DLL 传递数组参数问题
- VB调用vc写的dll的某个方法时的问题