分享

C语言的DLL怎么给VB返回String(char*)呢

 华灯初放l 2016-08-06

这个问题很少有资料可以搜索得到,主要是因为现在的程序员要么是C/C++,要么VB(.NET),

即有一种钟爱的语言.跟罗sir交流了一下,罗sir是C#骨灰级玩家,专攻网络开发,他认为DLL

加载到exe里成为一个模块,不能对上一级的变量赋值.

除了我这种患有代码痴迷症的人,不会有人去研究这个问题了,经过几天研究,发现了一些

窍门,最近又遇上用它的地方,所以干脆发达这里来,希望对大家有所帮助:

先介绍一个API,(Windows API主要是C语言的代码):

GetWindowText

GetWindowText(Byval hwnd As Long,Byval lpTitle As String,Byval sz As Long)

函数会把对应窗口的标题(文本)赋值给lpTitle,也就是说DLL是可以操作exe的变量的,DLL

属于exe就应当有exe赋予权利,娶个老婆回家,饭不给吃,钱不给用,所有东西不能动,这是哪家

哲学?好,我们现在来自己搞一个API,来给VB返回一个字符串:

.Code

Cpp代码
  1. #include "stdafx.h"//#include <windows.h>  
  2.   
  3. #define INSERT_API extern "C" _declspec(dllexport)  //定义接口宏定义  
  4.   
  5. BOOL APIENTRY DllMain( HANDLE hModule,   
  6.                        DWORD  ul_reason_for_call,   
  7.                        LPVOID lpReserved  
  8.                      )  
  9. {  
  10.     return TRUE;  
  11. }  
  12.   
  13. INSERT_API long __stdcall GetFileName(char *lpString,char lpResult[],long lngCount)  
  14. {   char *bytPos = lpString;                        //当前判断的指针  
  15.     char *bytGet = 0;       //分隔符的位置  
  16.     //if(*(lpString + 1) != ':') return 0x0000000F;  
  17.     if(*(lpString + 1) != 58) return 0x0000000F;      
  18.         //必须是 X:/..../XXXX.XXX  
  19.     if (*(lpString + 2) != '//') return 0x000000F0;  
  20.     char chrTemp = *(bytPos);                       //临时字符  
  21.     while(chrTemp)  
  22.     {   if(chrTemp == '//') bytGet = bytPos;  
  23.         bytPos++;chrTemp = *(bytPos);  
  24.     }  
  25.     if(*(bytGet + 1) == NULL) return 0x00000F00;    //C:/Windows/ 不带文件名  
  26.     long k;  
  27.     for(k = 0;k <= lngCount - 1;k++)  
  28.     {   chrTemp = *(++bytGet);  
  29.         if(chrTemp) {lpResult[k] = chrTemp;}else{break;}  
  30.     }  
  31.     return k;  
  32. }  

在.Def文件中添加这个函数名(前面有过VB,VC混合编程第一步的介绍),然后VB里面这样引用(这里最关键):

[Private/Public] Declare Function GetFileName Lib "XXX.DLL" (Byval lpString As String,Byval lpResult As String, _

Byval lngCount As String) As Long

然后就是缓冲区,底层开发除了要面对 [蓝屏] 就是 [崩溃],没有给变量缓冲区可能造成内存不能为Read的错误

Dim s As String,ss As String * 256

Rem 如果上面没有定长可以用 ss = space(256) 或者 ss = String(...)

s = "C:/windows/system32/shell32.dll"

Dim l As Long

l = GetFileName(s,ss,256)

ss = left(ss,l)

一个山寨版的 GetWindowText 就是这样了

关于//可能还有人问,前面有关于正则表达式的文章,看下就Okay了,就当前的问题,几个小地方要注意

VB跟C#累似(应该说C# 是vb和C/C++中走来),消去了指针,不要尝试给VB返回任何指针,VB可以用

AddressOf给一个API过程传递地址

VB的String和Byte数组是一个性质,API其实怎么声明无所谓,变量名本身是为了引用,传递的只是数

据类型

返回k的意义:

VB如果用space开辟缓冲区,trim了也就无所谓了,但是C/C++不同,就算你给下个元素赋值为NULL

字符串结束了,但是fwrite等函数还是会把整个数组搞进文件,所以返回k来确定字符窜的长度是很有

必要的

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多