聲明dll調用時如果有參數是 指針類型時 定義時需要在相應類型前面加上ref 表示傳遞的地址而不內容
ref +簡單類型
複雜類型 會自動將其地址複製一份進行傳遞
對簡單類型參數是否被ref修飾的區別在於:被修飾了的參數將以地址方式傳值;未被修飾的參數將以拷貝方式傳值。
對複雜類型參數是否被ref修飾的區別是相似的。由於複雜類型參數都以地址方式傳值,因而不被修飾時參數傳遞的是拷貝的地址;被修飾時參數傳遞的是真實地址。
下表說明了參數類型和ref 的關係。
簡單類型 | 複雜類型 | |
加ref | 地址 | 真實地址 |
不加ref | 拷貝 | 拷貝的地址 |
值得注意的是:結構的成員變量如果是複雜類型的話,雖不能在結構聲明中加ref,但它們將以真實地址方式傳值。此外,結構本身也是複雜類型。因此對結構變量的操作要小心,防止無意中的更改。
2、得到pb中某個字符串變量的地址
這次,單純依靠pb自身是行不通了,需要請來Win Api函數幫忙了:
主人公:Function long lstrcpy(ref string Destination, ref string Source) library "kernel32.dll"
原型:
The lstrcpy function copies a string to a buffer.
LPTSTR lstrcpy(
LPTSTR lpString1, // address of buffer
LPCTSTR lpString2 // address of string to copy
);
Return Values:If the function succeeds, the return value is a pointer to the buffer.
看我怎麼大顯身手:
定義實例變量:String is_dst
string ls_src
long ll_address
ls_src= "test me"
ls_dst =space(255)
ll_address=lstrcpy(ls_dst,ls_src) //將ls_src的內容複製到ls_dst,並返回ls_dst的存儲地址
麻煩是麻煩點,不過終於知道你藏身在ll_address那裏了。
3、在內存堆上分配空間,並存儲變量內容
這裏需要LocalAlloc,LocalFree,CopyMemory三個Api函數,其中LocalAlloc,LocalFree用來申請、釋放內存塊,CopyMemory用來複制內存塊。
這裏着重說明一下CopyMemory函數,有三個參數
PVOID Destination, // address of move destination
CONST VOID *Source, // address of block to move
DWORD Length // size, in bytes, of block to move
前兩個參數均是指針類型,因此我們可以根據需要在聲明中將其定義爲long或者ref ***的形式,反正都是指變量的地址,根據需要定義嘍!
例:
現在某個Api用到的某個結構中有一個long成員,用來存儲另外一個結構Menuitemdata的地址,以備將來所需。
結構menuitemdata 如下:
type menuitemdata from structure
unsignedlong hmenu
integer level
end type
好了,看看怎麼解決這個問題的。
相關外部函數聲明:
Function long LocalAlloc(long Flags, long Bytes) library "kernel32.dll"
Function long LocalFree(long MemHandle) library "kernel32.dll"
SUBROUTINE CopyMemory(long pDesc, ref menuitemdata pSrc,ulong size) LIBRARY "kernel32" ALIAS FOR "RtlMoveMemory"
SUBROUTINE CopyMemory(ref menuitemdata pDesc, long pSrc,ulong size) LIBRARY "kernel32" ALIAS FOR "RtlMoveMemory"
實例變量:long il_menuDataPointer
menuitemdata lpmenuitemdata
//下面代碼將lpmenuitemdata 的內容複製到內存塊il_menuDataPointer中
lpmenuitemdata.hmenu = 12345
lpmenuitemdata.level = 1
il_menuDataPointer= LocalAlloc(0,6) //6=sizeof(menuitemdata)
CopyMemory(il_menuDataPointer,lpmenuitemdata,6)
//那麼,如果再從內存塊中取出來呢??
CopyMemory(lpmenuitemdata,il_menuDataPointer,6)//很簡單吧!
//現在,我不需要 il_menuDataPointer這塊內存了
LocalFree(il_menuDataPointer)