您的位置:程序门 -> vb -> 基础类



vb中调用vc编译的dll的函数问题,50分送...


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


vb中调用vc编译的dll的函数问题,50分送...[已结贴,结贴人:goldenrod]
发表于:2007-08-22 16:43:20 楼主
我要调用同事编的vc编译的dll文件中的函数,用来读取本地两个文本文件,并查询文件中的数据,但是弄了很久,也不行.程序可以运行通过,但是在query函数中输入不同的englishtext变量,chinesetext的返回值是同样的27809这个数字,不是我需要的不同的中文字符串.我自觉是vc6中的这两个函数的声明不对,但是试验了很多种,都不行.请各位大侠多多指教,本人是vb菜鸟,非常感谢.


1.vc6中dll的原型如下:(vc中导出方式应该没有问题,加了stdcall方式,并且用def文件到处,此外用dependencies看过导出函数库了,名字没有变化..)
int   loadalldata(char   *filename1,   char   *filename2);
int   querydi(char   *strenglish,   unsigned   short   *strchinese);


2.vb6中声明如下
public   declare   function   loadalldata   lib   "query.dll "   (byval   filename1   as   string,   byval   filename2   as   string)   as   long
public   declare   function   query   lib   "query.dll "   (byval   strenglish   as   string,   byref   strchinese   as   integer)   as   long

3.vb6中调用主要如下:

dim   returnint   as   interget
dim   chinesetext   as   integer  
dim   englishtext   as   string
returnint   =   loadalldata( "input1.dat ", "input2.dat ")
returnint   =   query(englishtext,   chinesetext)
发表于:2007-08-22 16:47:231楼 得分:0
其中的loadalldata()函数是读取两个文本文件数据到缓冲区,然后query()函数是输入一个英文字符串,然后在前面读入的文本文件中查找相应字符串...
发表于:2007-08-22 17:16:262楼 得分:0
我刚才又查了一个返回的27809那个东西,如果转换成unicode码,就是 "没 "这个字.
我同事针对查不到的情况会返回 "没有对应中文 "这样的字符串.我在考虑,这个27809是不是就是我传进去了英文字符串,但是没有查到,所以返回了 "没有对应中文 "的第一个字符...
发表于:2007-08-22 17:56:213楼 得分:0
急啊,没有人知道怎么回事吗?          
我又查了一下,那个27809,不是我在2楼猜测的原因
发表于:2007-08-22 20:08:594楼 得分:20
int   querydi(char   *strenglish,   unsigned   short   *strchinese);

后面那个东西,在vc   dll里面是不是一个指向字符串缓冲区的指针?

如果是,那么你的声明就改成这样:

public   declare   function   query   lib   "query.dll "   (byval   strenglish   as   string,   byval   strchinese   as   string)   as   long

同时在调用时,为strchinese变量分配足够的长度,如下:

dim   returnint   as   interget
dim   chinesetext   as   string   *   255     '这里分配255个字节的长度  
dim   englishtext   as   string

returnint   =   loadalldata( "input1.dat ", "input2.dat ")
returnint   =   query(englishtext,   chinesetext)

在最后,我还想明白一下,你第一个loadalldata函数的两个参数,文件名确定没问题?(你没有带路径,文件是否放在了工程目录下?)
发表于:2007-08-22 22:24:205楼 得分:0
谢谢myjian的帮助,不过我按照你说的尝试了,还是不行...每次查询出来就是一堆乱码了....

我的第一个loadalldata函数中两个参数都是文件名,检查过没有错误,都没有带路径,并且都是放在工程目录下的.但是我同事在vc里面是用fopen(wb方式)打开这两个文件的,不是wfopen,我不知道此处vb里面传string进去行不行,因为听说vb里面的string是unicode形式的.但是我看了这个loadalldata的返回值,是-1,我同事定义的只有return   1才是正常执行了.我觉得这个函数在vb里面没有正常执行.

还有就是第二个函数,我按照你贴出来的修改了,还是不行.查询出来每次都是同样的乱码.这个函数里面第一个参数是需要查询的英文字符串(char   *,   即用acii码),第二个参数是用来得到输出的中文字符串(这里用unsingend   short来保存对应的unicode码),是一个指向缓冲区的指针.

又搞了好久,还是出不来,都快发疯了...


发表于:2007-08-22 22:33:096楼 得分:0
我不清除这里面在vc里面用char   *的参数,vb里面用string声明可不可以,不知道vb会不会自动转换的.

不过我也尝试过把参数声明成byte数组,然后将文件名转换成ansi码,再对这个byte数组最后一位强制写成\0,但是调用loadalldata后,watch   返回值returnlong还是-1.....

以下是我按照这种方式调用的部分代码
-------------------------------------------------
vb声明:
public   declare   function   loadalldata   lib   "query.dll "   (byref   strengfilename()   as   byte,   byref   strchinfilename()   as   byte)   as   long
public   declare   function   query   lib   "query.dll "   (byref   strenglish()   as   byte,   byref   strchinese   as   string)   as   long

vb调用:
dim   fileen()   as   byte
dim   filech()   as   byte

fileen   =   strconv( "engasciidi.dat0 ",   vbfromunicode)
fileen(14)   =   fileen(14)   -   48                                                 '让fileen数组最后一个字节为/0
filech   =   strconv( "chinunicodedi.dat0 ",   vbfromunicode)
filech(17)   =   filech(17)   -   48                                               '让fileen数组最后一个字节为/0
returnlong   =   loadalldata(fileen,   filech)
发表于:2007-08-22 23:32:027楼 得分:0
还是没解决......
我现在觉得,应该是按照这样声明,但是还是不行.....真是郁闷啊...各位老大啊,就帮帮小弟偶吧
-----------------------------------------------------------------
vb   声明
public   declare   function   loadalldidata   lib   "querydi.dll "   (byval   strengfilename   as   string,   byval   strchinfilename   as   string)   as   long
public   declare   function   querydi   lib   "querydi.dll "   (byval   strenglish   as   string,   byref   strchinese()   as   byte)   as   long

vb调用
dim   returnlong   as   long
dim   englishtext   as   string
dim   chinesetext(255)   as   byte

returnlong   =   loadalldidata( "engasciidi.dat ",   "chinunicodedi.dat ")
returnlong   =   querydi(englishtext,   chinesetext)  
发表于:2007-08-23 00:46:068楼 得分:0
把你的vc代码贴出来我帮你看看
发表于:2007-08-23 01:31:399楼 得分:0
vc的代码好多的,几千行....贴不完
我就贴第一个函数好了,chenhui530帮我看看,我觉得我调用后returnlong那个返回-1是错的..应该就没有执行   loadalldidata函数成功,应该是这里有问题.

vb里面声明和调用方式我查了很多资料,也尝试了不同的方式,然后觉得还是myjian(嗷嗷叫的老马--无视无视~~)说的对,不过还是有点糊涂的.


下面是vc的部分代码
--------------------------------------------
/************************************************************************/
/*   从文件中load所有di数据                                                                                                   */
/************************************************************************/
int   loadalldidata(searchdidata   &searchdata,   char   *strengfilename,   char   *strchinfilename)
{

file   *pfeng   =   0;
file   *pfchin   =   0;
long   lheaderitemsize   =   0;
long   lheadernumber   =   0;
long   lposoffset   =   0;
long   lposengoffset   =   0;
long   lposchinoffset   =   0;
int   nsumcount   =   0;
int   ndatacount   =   0;
char   buf[256];
unsigned   short   wchin[256];
long   lfirstposeng   =   0;
long   lfirstposchin   =   0;
if   ((pfeng   =   fopen(strengfilename,   "rb "))   ==   0)
{
printf( "error   open   eng ");
return   -1;
}

if   ((pfchin   =   fopen(strchinfilename,   "rb "))   ==0)
{
printf( "error   open   chinse ");
return   -1;
}


memset(buf,   0x00,   sizeof(buf));
if   (fgets(buf,   sizeof(buf),   pfeng)   ==   0)
{
fclose(pfeng);
return   -2;
}
buf[strlen(buf)-1]   =   '\0 ';
lheadernumber   =   atol(buf);

memset(buf,   0x00,   sizeof(buf));
if   (fgets(buf,   sizeof(buf),   pfeng)   ==   0)
{
fclose(pfeng);
return   -2;
}
buf[strlen(buf)-1]   =   '\0 ';
lheaderitemsize   =   atol(buf);

for   (int   i   =0;   i <lheadernumber;   i++)
{
memset(buf,   0x00,   sizeof(buf));
if   (fgets(buf,   sizeof(buf),   pfeng)   ==   0)
{
fclose(pfeng);
return   -2;
}
searchdata.chrpos[i].ch   =   getcharacterletter(buf);
getfstpostion(buf,   ndatacount,   lposengoffset,   lposchinoffset);
if   (i   ==   0)
{
lfirstposeng   =   lposengoffset;
lfirstposchin   =   lposchinoffset;

}
searchdata.chrpos[i].ncount   =   ndatacount;
searchdata.chrpos[i].nfsrpos   =   nsumcount;
nsumcount   +=   ndatacount;
}

fseek(pfeng,   lfirstposeng,   seek_set);
fseek(pfchin,   lfirstposchin,   seek_set);
for   (i   =0;   i <nsumcount;   i++)
{
memset(buf,   0x00,   sizeof(buf));
if   (fgets(buf,   sizeof(buf),   pfeng)   ==   0)
{
fclose(pfeng);
fclose(pfchin);
return   -1;
}
buf[strlen(buf)-1]   =   '\0 ';
memset(wchin,   0x00,   sizeof(wchin));
if   (fgetws(wchin,   sizeof(wchin),   pfchin)   ==   0)
{
fclose(pfeng);
fclose(pfchin);
return   -1;
}
wchin[wcslen(wchin)-1]   =   0x00;
strcpy(searchdata.data[i].streng,   buf);
wcscpy(searchdata.data[i].strchinese,   wchin);
}
fclose(pfeng);
fclose(pfchin);
return   1;

}

------------------------------------------
/************************************************************************/
/*   di写入内存结构                                                                                                               */
/************************************************************************/
typedef   struct   tysearchdi
{
position   chrpos[27];
eledi   data[11000];
}searchdidata
发表于:2007-08-23 01:41:3910楼 得分:0
另一个导出函数如下,   这些代码我同事在vc下测试过(不是通过dll方式),是把.cpp和.h加入到已有的项目里面可以运行的.     我现在在vb里面,可以运行,没有那种找不到entry   point的常规错误,   querydi返回0,   loadalldidata返回-1.谢谢帮忙看看.


/************************************************************************/
/*   查询di                                                                                                                               */
/************************************************************************/
int   querydi(char   *strenglish,   unsigned   short   *strchinese,   searchdidata   searchdata)
{
wcscpy(strchinese,   strnoitemchi);
int   nstart   =   0;
int   ncount   =   0;
int   ret   =   0;
if   ((strenglish   ==   0) ¦ ¦
(strchinese   ==   0))
{

return   -1;
}
if   (isnormalchar(*strenglish))
{
nstart   =   searchdata.chrpos[*strenglish   -   'a '].nfsrpos;
ncount   =   searchdata.chrpos[*strenglish   -   'a '].ncount;
}
else
{
nstart   =   searchdata.chrpos[26].nfsrpos;
ncount   =   searchdata.chrpos[26].ncount;

}
ret   =   dichotomydi(searchdata.data,   nstart,   ncount,   strenglish);
if   (ret   > =0)
{
wcscpy(strchinese,   searchdata.data[ret].strchinese);
return   1;
}
return   0;

}
发表于:2007-08-23 09:02:3411楼 得分:0
问题
1、你要调用的是函数   query,但是给我们看的声明却是   querydi,请明确
2、query   函数实现什么功能?两个参数是否都是   out   的?如果第一个是   in   的,那么   vb   调用中   englishtext   变量没有赋任何值!
发表于:2007-08-23 09:18:0412楼 得分:0
tiger_zhao,我那个函数名是后面改过,问题不是这个.
querydi中,第一个是输入的英文字符串(char*)是英文的;第二个是输出的中文字符串(unsigned   short*),是out的.
关于你说的englishtext我在程序里面取得了别的值,也是string类型的,这里没有列出.
发表于:2007-08-23 09:20:5813楼 得分:0
query就是querydi,我后面改过了的
发表于:2007-08-23 10:01:5614楼 得分:30
方案一:
public   declare   function   query   lib   "query.dll "   (byval   strenglish   as   string,   byref   strchinese   as   string)   as   long

chinesetext   =   space(256)   '需要有足够输出的空间
rnint   =   query(englishtext,   chinesetext)

如果   chinesetext   为乱码,试试用下面的两个方法之一再转换一下
chinesetext   =   strconv(chinesetext,   vbfromunicode)
chinesetext   =   strconv(chinesetext,   vbunicode)

方案二:
public   declare   function   query   lib   "query.dll "   (byval   strenglish   as   string,   byval   strchinese   as   long)   as   long

dim   a()   as   byte
redim   a(512)   '需要有足够输出的空间
rnint   =   query(englishtext,   varptr(a(0)))
chinesetext   =   a
发表于:2007-08-23 10:41:0915楼 得分:0
我顶顶~~~~今天感冒了,头有点晕
发表于:2007-08-23 14:17:1116楼 得分:0
我现在确定了是loadalldidata函数调用的时候就有问题了,我在vc里面又把返回值改过了,然后确定现在是在loadalldidata里面现在就有问题了.
因为我在vb里loadalldidata时返回9.
相应的vc中,我把loadalldidata函数中打开英文文件的地方改成了如下;
if   ((pfeng   =   fopen(strengfilename,   "rb "))   ==   0)
{
printf( "error   open   eng ");
return   -9;
}
---------------------------------
应该是vb里面传的英文文件名就没有传进去...这种情况该怎么处理?
发表于:2007-08-23 14:20:2117楼 得分:0
后面那个函数querydi函数,我现在用过查出来的是在vc里面定义的常量的unicode的little   endian形式.   这个问题可以先放下,我现在最想知道的是,我为什么调用那个loadalldidata函数居然也传不进去文件名....


发表于:2007-08-23 14:36:4118楼 得分:0
刚才又尝试了,不再传参,直接在vc的dll源程序里面就把loadalldata()中,让
if   ((pfeng   =   fopen( "engasciidi.dat ",   "rb "))   ==   0)
{
printf( "error   open   eng ");
return   -9;
}
这样都不行,返回值仍然是-9....
搞不定了....
发表于:2007-08-23 23:36:0719楼 得分:0
搞不定了?

那就先不要结帖子啊,搞定再说


快速检索

最新资讯
热门点击