您的位置:首页 > 编程语言 > C语言/C++

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条建议。

          不管怎么说终于解决了问题,呵呵。。尽管自己不是软件出身,但是毕竟又增长了不少见识和知识。。仓促些,但还是记下来吧。。希望有所裨益!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息