S
staven
Unregistered / Unconfirmed
GUEST, unregistred user!
最近写了一个dll,调用windowsApi中的dll,出现了几个怪现象。望大家帮忙解答一下。
windows api中的函数原形:
function SCardListReaders(
const hContext: SCARDCONTEXT
//SCARDCONTEXT实际上是ulong类型
mszGroups: PChar
mszReaders: LPSTR
//LPSTR实际上是pchar类型
pcchReaders: LPDWORD): Longint
stdcall
//LPDWORD也就是pDword类型
我编写的dll中声明了一个函数,供外部调用,该函数调用了上面的windows api函数。该函数的源码如下:
function SCListReaders(Readers: pchar): longint;stdcall;
var
m_ReaderBuff: pchar
// } array[0..255] of char
[red]//注意,这里我声明了2种类型[/red]
dwRetCode: longint;
m_ReaderBuffLen: DWORD;
nPtr: integer;
myReaders: string;
begin
result := E_success;
//读卡器初始化
if not readersInited then
begin
result := SCinitReaders;
if result <> E_success then exit;
end;
//读读卡器列表
m_ReaderBuff := AllocMem(256);
try
dwRetCode := SCardListReaders(m_Context,
nil,
m_ReaderBuff, //}@m_ReaderBuff[0], [red] //这里是注意点,有2种方式[/red]
@m_ReaderBuffLen);
if (dwRetCode <> SCARD_S_SUCCESS) then begin
result := E_ReadersListFailed;
exit;
end;
setlength(myReaders, m_ReaderBuffLen - 1);
move(m_ReaderBuff^, myReaders[1], m_ReaderBuffLen - 1)
finally
FreeMem(m_ReaderBuff, 256)
end;
StrPCopy(readers, myReaders);
end;
问题出在对m_ReaderBuff的使用上,出现了下面几个问题:
1、把m_ReaderBuff定义成array[0..255] of char的时候,经常会出现调用不成功的情况(传的是@m_ReaderBuff[0],或者m_ReaderBuff),后来就一次也没成功了。按理来说没有什么问题啊。但是把m_ReaderBuff放到函数体外,又可以了。不知道怎么回事?
dwRetCode := SCardListReaders(m_Context, nil, @m_ReaderBuff[0], m_ReaderBuffLen);
2、把m_ReaderBuff定义成pchar的时候,一般会调用成功,就如现在的代码。当然内存是申请过了。但是发现传出来的值都是空值,很奇怪。
dwRetCode := SCardListReaders(m_Context, nil, m_ReaderBuff, m_ReaderBuffLen);
3、最后来,我把m_ReaderBuff定义成pointer,发现可以调用成功,值也正确读出来了。
dwRetCode := SCardListReaders(m_Context, nil, m_ReaderBuff, m_ReaderBuffLen);
4、我也试过把m_ReaderBuff定义成string类型,可以调用成功,但是传出来的值也都是空值。奇怪!(不要怀疑没有申请内存)。
dwRetCode := SCardListReaders(m_Context, nil, @m_ReaderBuff[1], m_ReaderBuffLen);
5、最后,随着程序的进行,我把代码删掉了几行,就又发现取出来的值不对了,但是可以成功调用。
上面的现象真是奇怪,不知道大家是否碰到过。
从现象来看,感觉是内存分配,读取地址出现了什么问题,好像string和pchar互相转化之间出现了混乱。后来我试过,变了一个可执行程序,引用该代码单元,不管采用什么类型声明,这些代码都没有问题。难道dll编写这样的代码,有什么需要注意的地方么?
希望大家不吝赐教!(分数多的是)
windows api中的函数原形:
function SCardListReaders(
const hContext: SCARDCONTEXT
//SCARDCONTEXT实际上是ulong类型
mszGroups: PChar
mszReaders: LPSTR
//LPSTR实际上是pchar类型
pcchReaders: LPDWORD): Longint
stdcall
//LPDWORD也就是pDword类型
我编写的dll中声明了一个函数,供外部调用,该函数调用了上面的windows api函数。该函数的源码如下:
function SCListReaders(Readers: pchar): longint;stdcall;
var
m_ReaderBuff: pchar
// } array[0..255] of char
[red]//注意,这里我声明了2种类型[/red]
dwRetCode: longint;
m_ReaderBuffLen: DWORD;
nPtr: integer;
myReaders: string;
begin
result := E_success;
//读卡器初始化
if not readersInited then
begin
result := SCinitReaders;
if result <> E_success then exit;
end;
//读读卡器列表
m_ReaderBuff := AllocMem(256);
try
dwRetCode := SCardListReaders(m_Context,
nil,
m_ReaderBuff, //}@m_ReaderBuff[0], [red] //这里是注意点,有2种方式[/red]
@m_ReaderBuffLen);
if (dwRetCode <> SCARD_S_SUCCESS) then begin
result := E_ReadersListFailed;
exit;
end;
setlength(myReaders, m_ReaderBuffLen - 1);
move(m_ReaderBuff^, myReaders[1], m_ReaderBuffLen - 1)
finally
FreeMem(m_ReaderBuff, 256)
end;
StrPCopy(readers, myReaders);
end;
问题出在对m_ReaderBuff的使用上,出现了下面几个问题:
1、把m_ReaderBuff定义成array[0..255] of char的时候,经常会出现调用不成功的情况(传的是@m_ReaderBuff[0],或者m_ReaderBuff),后来就一次也没成功了。按理来说没有什么问题啊。但是把m_ReaderBuff放到函数体外,又可以了。不知道怎么回事?
dwRetCode := SCardListReaders(m_Context, nil, @m_ReaderBuff[0], m_ReaderBuffLen);
2、把m_ReaderBuff定义成pchar的时候,一般会调用成功,就如现在的代码。当然内存是申请过了。但是发现传出来的值都是空值,很奇怪。
dwRetCode := SCardListReaders(m_Context, nil, m_ReaderBuff, m_ReaderBuffLen);
3、最后来,我把m_ReaderBuff定义成pointer,发现可以调用成功,值也正确读出来了。
dwRetCode := SCardListReaders(m_Context, nil, m_ReaderBuff, m_ReaderBuffLen);
4、我也试过把m_ReaderBuff定义成string类型,可以调用成功,但是传出来的值也都是空值。奇怪!(不要怀疑没有申请内存)。
dwRetCode := SCardListReaders(m_Context, nil, @m_ReaderBuff[1], m_ReaderBuffLen);
5、最后,随着程序的进行,我把代码删掉了几行,就又发现取出来的值不对了,但是可以成功调用。
上面的现象真是奇怪,不知道大家是否碰到过。
从现象来看,感觉是内存分配,读取地址出现了什么问题,好像string和pchar互相转化之间出现了混乱。后来我试过,变了一个可执行程序,引用该代码单元,不管采用什么类型声明,这些代码都没有问题。难道dll编写这样的代码,有什么需要注意的地方么?
希望大家不吝赐教!(分数多的是)