在PB中如何獲取變數的地址?謝謝!
uj5u.com熱心網友回復:
看看幫助檔案,記得好像在哪兒看到過,沒查,見諒uj5u.com熱心網友回復:
PB中如何得到一個字串變數的地址在PB中,經常會需要呼叫一些動態庫(DLL)來實作功能的擴展,但DLL一般都是C語言或Delphi語言寫的,常常
會使用指標,給出的引數也常常是指標形式的。雖然PB中可以加上REF關鍵字來指明傳遞的是引數地址,但實際使用中
卻往往會出一些意想不到的結果,我最近在呼叫一個DLL時,使用REF傳遞一個字串給DLL,但最后DLL取到的卻是一串
亂碼,這說明傳給DLL的地址錯了,DLL取到了別的記憶體塊的資料,此時,PB只能望針興嘆了。
其實,在有些時候,我們還是可以變通地使用一些其他辦法來迂回地操作指標的。下面是我實際使用的通過
Windows API來取到字串地址的方法:
一、首先宣告一個API函式:
Function long lstrcpy(ref string Destination, ref string Source) library "kernel32.dll" ALIAS FOR
"lstrcpy;ansi";
二、再呼叫上面的函式來得到字串地址:
String ls_src, ls_dst
long ll_address
ls_src = "PB中如何得到一個字串變數的地址"
ls_dst = space(255)
ll_address=lstrcpy(ls_dst, ls_src )
這樣,ll_address中得到的就是字串ls_dst的地址了,我有一個C語言寫的DLL,其中一個函式是這樣的:
void __stdcall ChangePrinterSetting(LPTSTR pCustomFormName, SIZEL* FormSize);
按照正常的方式,在PB里應該這樣宣告并呼叫:
public FUNCTION Integer ChangePrinterSetting(REF string formName, REF STRU_SIZEL size) LIBRARY
"PrnSet.dll" ALIAS FOR "ChangePrinterSetting;ansi";
String ls_fromName
STRU_SIZEL size;
ls_fromName = "我的表單格式"
size.cx = 100000
size.cy = 200000
ChangePrinterSetting(ls_fromName, size)
但這樣呼叫,實際運行發現,DLL中取到的是亂碼,說明通過REF關鍵字傳遞給DLL的引數地址錯了,于是我改成這種方
式:
public FUNCTION Integer ChangePrinterSetting(long formName, REF STRU_SIZEL size) LIBRARY "PrnSet.dll"
ALIAS FOR "ChangePrinterSetting;ansi";
String ls_fromName, ls_temp
STRU_SIZEL size;
ls_fromName = "我的表單格式"
ls_temp = space(255)
ll_address=lstrcpy(ls_temp, ls_fromName)
size.cx = 100000
size.cy = 200000
ChangePrinterSetting(ll_address, size)
這樣,DLL里就取到了正確的中文字串。這樣多寫了幾行代碼,保存了引數正確傳遞,也算是沒有辦法的辦法吧。
總得說來,PB對于快速開發資料庫應用方面的確有其獨特的優勢,但遇到需要用第三方語言來擴展功能的時候,就
顯得力不從心了。
uj5u.com熱心網友回復:
碼克。。。uj5u.com熱心網友回復:
學習,謝謝奉獻。uj5u.com熱心網友回復:
學習了uj5u.com熱心網友回復:
告訴你寫一個API:ULONG WINAPI getpointer(LPVOID Variable)
PB宣告:
function ulong getpointer(ref string s) ....
function ulong getpointer(ref char s) ....
function ulong getpointer(ref long s) ....
.....
看大家看得懂不,看不懂,也別多問了。。。。
uj5u.com熱心網友回復:
函式體忘寫了:ULONG WINAPI getpointer(LPVOID Variable)
{
return (ULONG)Variable;
}
uj5u.com熱心網友回復:
學習了uj5u.com熱心網友回復:
看來是個高深問題.uj5u.com熱心網友回復:
試一下~~行不行`uj5u.com熱心網友回復:
以后有問題直接打劫新意兄就行了。這兄弟存貨太多了。呵呵uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
怎么會有亂碼呢?不解!
BOOL AddOpenCom(LPCTSTR coms,LPCTSTR commset,LPCTSTR outerr_text)
{
__try
{
COMHREAD *h;
if(FindCom(coms))
return TRUE;
h = Initializationcomobj(coms,commset);
if(!OpenCom(&h->com.hcom,coms,commset,TRUE,outerr_text))
{
DeleteComobj(h);
return FALSE;
}
h->com.portopen = TRUE;
if(!comobjs)
{
comobjs = h;
}
else
{
comobjs->back = h;
h->next = comobjs;
comobjs = h;
}
::InitializeCriticalSection(&h->com.cs);
h->comthread = CreateThread(NULL, 0, ListenThread, (LPVOID)h, 0, NULL);
return TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
sprintf((CHAR*)outerr_text,"發生了未知了錯誤!");
return FALSE;
}
}
function BOOLean AddOpenCom(ref string coms,ref string commset,ref string outerr_text) library "vscomm.dll" alias for "AddOpenCom;Ansi"
if isnull(com) then return
try
datastore rs;rs = create datastore;rs.dataobject = "d_coms_select";rs.settransobject(sqlca)
rs.setsqlselect(rs.getsqlselect() + " and fact_no = '" + as_fact_no + "' and com ='" + com + "'");rs.retrieve()
string coms,err_text
long n,ll_count,f
ll_count = rs.rowcount()
if ll_count = 0 then
return
end if
ServiceManager services
n_data nvo_data
services.LoadService(nvo_data, "n_data")
for n = 1 to ll_count
coms = rs.getitemstring(n,"com")
err_text = space(400)
if AddOpenCom(coms,comset,err_text) then
f = nvo_data.rs.find("com='" + coms + "'",1,nvo_data.rs.rowcount())
if f > 0 then
nvo_data.rs.setitem(f,"status_text","運行正常.")
nvo_data.rs.setitem(f,"status","Y")
else
f=nvo_data.rs.insertrow(0)
nvo_data.rs.setitem(f,"com",coms)
nvo_data.rs.setitem(f,"status_text","運行正常.")
nvo_data.rs.setitem(f,"status","Y")
end if
else
f = nvo_data.rs.find("com='" + coms + "'",1,nvo_data.rs.rowcount())
if f > 0 then
nvo_data.rs.setitem(f,"status_text",trim(err_text))
nvo_data.rs.setitem(f,"status","N")
else
f=nvo_data.rs.insertrow(0)
nvo_data.rs.setitem(f,"com",coms)
nvo_data.rs.setitem(f,"status_text",trim(err_text))
nvo_data.rs.setitem(f,"status","N")
end if
end if
end for
catch(runtimeerror ex)
return
finally
destroy rs
end try
uj5u.com熱心網友回復:
像我一般都是像上面的那樣用,從來不亂碼!如果是結構體的自寫API,那么就加#pragma pack(1),因為默認會有記憶體對齊,這樣你PB傳就不準了.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#pragma pack(1)
#define SENDBOF 0X3A
#define BACKBOF 0X2A
#define DATAEOF 0X0A
#define WRITEDATETIME 0x74 //寫日期時間,t
typedef struct//COM物件
{
LPCTSTR com;//埠名
LPCTSTR commset;//埠引數
BOOL portopen;//埠打開狀態
HANDLE hcom;
CRITICAL_SECTION cs;
}COMOBJECT;
typedef struct COMHREAD
{
COMOBJECT com;
HANDLE comthread;
COMHREAD* back;
COMHREAD* next;
}COMHREAD;
typedef struct
{
LONG lenght;
BYTE data[100];
}PACKAGE;
typedef struct CWORKDATE
{
SYSTEMTIME cwork_begin;
SYSTEMTIME cwork_end;
}CWORKDATE;
typedef struct
{
BYTE workmk;
BYTE timemk;
LONG timestep;
LONG wlen;
CWORKDATE wdt[500];
}INFODATA;
typedef struct
{
INFODATA data;
}RUNINFO;
#pragma pack()
uj5u.com熱心網友回復:
學習,謝謝奉獻。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/82588.html
標籤:腳本語言
下一篇:MQ 連接問題
