最近的项目中的一个DLL的接口如下:
 FINANCE_API bool LoadFile(const char* szFile, char** szBuf,const char* szKey,char szErrMsg[],const char* szCorp,const char* szType,int iVer); 
在VB中如何调用?主要是三种类型:const char*,char**,char szErrMsg[],尤其是char**的调用,请各路大侠指教。

解决方案 »

  1.   

    char **的类型本来在C++中就不应该常用,如果是在函数内部分配的内存不好在外面释放,释放的问题你自己考虑。修改VB的字符串指针可以获得读取这块内存。试试看用ByRef szBuf as String看看,如果不行用szBuf as Any,然后利用CopyMemory这个API把szBuf的指针内容Copy到一个String的指针上:
    Dim VBszBuf as String
    Dim OrgP as long
    '修改VBszBuf的长度
    VBszBuf=Space(n) 'n是可能的长度
    CopyMemory(varptr(OrgP),varptr(VBszBuf),4)  '保存原来的指针
    CopyMemory(varptr(VBszBuf),varptr(szBuf), 4) '替换String指针
    '现在你可以使用VBszBuf来访问数据了CopyMemory(varptr(VBszBuf),varptr(OrgP),4) '还原String指针。
      

  2.   

    因该是和调用API函数差不多!!!
      

  3.   

    关于内存的释放是由DLL中另外一个函数FreeBuffer来实现的SnHnBn大大说的szBuf as Any中的Any是虾米?VB中没有这个类型呀?是不是Variant呀?btw.有人告诉我让我用VC调用DLL,再编一个ATL COM,这样再让VB来调用,难道非要这样脱裤子放屁吗?-_-|||
      

  4.   

    或许这个dll就不是样vb来调用的,可能是让c来调用的,因为里面的很多参数都是针对c的
    也许你把这个函数改编一下来直接使用
      

  5.   

    dll的源程序我是碰不着的说 :(
      

  6.   

    Any是任意类型,按照ByRef传就传的是变量的地址。既然用到char**,极大可能在函数体内重新分配内存,所以返回的值是一个地址。所以照我看来,
    LoadFile(const char* szFile, //ByVal szFile as String 
             char** szBuf,       //ByRef szBuf as Any
             const char* szKey,  //ByVal szKey as String
             char szErrMsg[],    //ByVal szErrMsg as String
             const char* szCorp, //ByVal szCorp as String
             const char* szType, //ByVal szType as String
             int iVer            //ByVal iVer as Long
    );      Dim szBuf as LongLoadFile szFile, szBuf, szKey, szErrMsg, szCorp,szType, iVer 
    szBuf的值就是新分配内存空间的首地址。奇怪的是既然分配了内存给Buff,规范一些的应该有Buff的长度给出。大概这块Buff以'\0'结束?
    接着可以用CopyMemory得到buff的数据:
    但是你的API声明CopyMemory必须做一个新的更改,姑且称之为CopyMemory1
    CopyMemory1 ByRef Dest as Any, ByVal Src as long, Length as Long 
    //假设长度是BuffSize
    Dim byBuff(0 to BuffSize - 1) as ByteCopyMemory1 byBuff(0), szBuff, BuffSize用完后释放空间
    FreeBuffer(char** Buff)就声明FreeBuff(ByRef Buff as long)
    FreeBuffer(char* Buff)就声明FreeBuff(ByVal Buff as long)
    FreeBuffer(szBuff)即可
      

  7.   

    按照lazygod兄的方法调用,仍然提示“DLL 的调用约定错误(错误 49)”的错误
    另外,lazygod兄的写法中有个错误,LoadFile这个函数是有一个bool的返回值的~~另外这个函数中,szBuf和szErrMsg需要输出的变量,而且dll的说明中明确指出在调用函数前szErrMsg是一定要初始化的。对于这点我的理解就是szBuf是在函数内部分配内存的,而szErrMsg则是在函数外就要分配好内存的首地址~~
      

  8.   

    你把返回值补上就可以了,bool应该对应As byte
      

  9.   

    初始化就象我前面说的szErrMsg=Space(n) 'n就是要分配的长度。
      

  10.   

    还是可恶的“DLL 的调用约定错误(错误 49)”-_-|||定义:
    Declare Function LoadFile Lib "dll文件名" (ByVal szFile _
                    As String, ByRef szBuf As Any, ByVal szKey As String, ByVal _
                    szErrMsg As String, ByVal szCorp As String, ByVal szType As _
                    String, ByVal iVer As Long) As Byte
    调用:
    Dim szBuf As Long
    Dim szErrMsg As String
    Dim ret As ByteszErrMsg = Space(1024)ret = LoadFile("c:\temp\test.pam", szBuf, "", szErrMsg, "000", "", 20)请大大继续指教~~
      

  11.   

    最后一个参数类型不对,把20改成20&试试看。
      

  12.   

    这种错误应该是要注意你的DLL 定义的FINANCE_API到底是什么?一定要stdcall的定义才行的。
      

  13.   

    DLL的源文件我是看不到也改不了的说,这个dll可以在vc、c++ builder中正常调用
      

  14.   

    我把20改成20&同样不行,dll的定义估计和我顶楼写的相同,那么是不是说就不能用vb直接调用了?
      

  15.   

    “这个dll可以在vc、c++ builder中正常调用”
    你是怎么调用的?就是你申明的函数原型是什么?
    是不是就是“FINANCE_API bool LoadFile(const char* szFile, char** szBuf,const char* szKey,char szErrMsg[],const char* szCorp,const char* szType,int iVer); ”
    哪你查查FINANCE_API是什么的定义?
    或者直接声明为“bool LoadFile(const char* szFile, char** szBuf,const char* szKey,char szErrMsg[],const char* szCorp,const char* szType,int iVer); ”
    这种情况下编译器默认是_cdecl 而不是 stdcall,如果是这样就没有办法在VB中直接调用了。
      

  16.   

    我看到的接口里是没有stdcall的,而“在vc、c++ builder中正常调用”是这样做的:typedef bool (*FBLoadFile)(const char* szFile,
                               char** szBuf,
                               const char* szKey,
                               char szErrMsg[],
                               const char* szCorp,
                               const char* szType,
                               int iVer);
    FBLoadFile pLoadFile;
    pLoadFile = (FBLoadFile)(::GetProcAddress(hFinance, "LoadFile"));估计正如楼上兄台所讲,这个api不能让vb直接调用,后来我有自己编了一个com控件,让vb调用com控件这种方法来曲线救国~~
      

  17.   

    对喽,这种定义默认是_cdecl调用约定。VB调API只能调_stdcall标准调用约定的函数。