Declaring API externs with structures
BlitzMax Forums/BlitzMax Programming/Declaring API externs with structures
| ||
I am attempting to call some Win32 API functions which take structures (types). Has anyone had any experience with this? I haven't been able to get it to work...SuperStrict Import "-lkernel32" Const TH32CS_SNAPPROCESS:Int = 2 Const MAX_PATH:Int = 260 Type PROCESSENTRY32 Field dwSize:Int Field cntUsage:Int Field th32ProcessID:Int Field th32DefaultHeapID:Int Field th32ModuleID:Int Field cntThreads:Int Field th32ParentProcessID:Int Field pcPriClassBase:Int Field dwFlags:Int Field szExeFile:String End Type Extern "Win32" Function WinExec(lpCmdLine:Byte Ptr,nCmdShow:Int)="WinExec@8" Function CreateToolhelp32Snapshot:Int(lFlags:Int, lProcessID:Int) Function ProcessFirst(hSnapShot:Int, uProcess:PROCESSENTRY32 Ptr) Function ProcessNext(hSnapShot:Int, uProcess:PROCESSENTRY32 Ptr) Function CloseHandle(hPass:Int) End Extern Error: Compile Error: Illegal pointer type [Projects/max/dllp/process_list.bmx;24;2] Build Error: failed to compile Projects/max/dllp/process_list.bmx Process complete I also tried declaring ProcessFirst and ProcessNext with integers as their second argument, which obviously doesn't work either. |
| ||
Something like this I think:SuperStrict Framework brl.basic Import "-lkernel32" Const TH32CS_SNAPPROCESS:Int = 2 Const MAX_PATH:Int = 260 Type PROCESSENTRY32 Field dwSize:Int Field cntUsage:Int Field th32ProcessID:Int Field th32DefaultHeapID:Int Field th32ModuleID:Int Field cntThreads:Int Field th32ParentProcessID:Int Field pcPriClassBase:Int Field dwFlags:Int Field szExeFile:String End Type Extern "Win32" Function WinExec(lpCmdLine:Byte Ptr,nCmdShow:Int) = "WinExec@8" Function CreateToolhelp32Snapshot:Int(lFlags:Int, lProcessID:Int) Function ProcessFirst(hSnapShot:Int, uProcess:Byte Ptr) Function ProcessNext(hSnapShot:Int, uProcess:Byte Ptr) Function CloseHandle(hPass:Int) End Extern ' Global pe:PROCESSENTRY32=New PROCESSENTRY32 ' result=ProcessFirst(0,Byte Ptr(pe)) |
| ||
hmm, the last thread with this code must have been lost as I posted working version but can't now find it. to get you started here is: .. see below now you need to create a new processentry32 struct, assign dwSize to sizeof(processentry32), rename your Process functions to Proces32 and you should be away... |
| ||
SuperStrict Const TH32CS_SNAPPROCESS:Int = 2 Type PROCESSENTRY32 Field dwSize:Int Field cntUsage:Int Field th32ProcessID:Int Field th32DefaultHeapID:Int Field th32ModuleID:Int Field cntThreads:Int Field th32ParentProcessID:Int Field pcPriClassBase:Int Field dwFlags:Int Field szExeFile:Byte,b1:Byte,b2:Byte,b3:Byte '4 + 256=260 bytes for path Field p0:Long,p1:Long,p2:Long,p3:Long Field p4:Long,p5:Long,p6:Long,p7:Long Field p8:Long,p9:Long,pa:Long,pb:Long Field pc:Long,pd:Long,pe:Long,pf:Long Field q0:Long,q1:Long,q2:Long,q3:Long Field q4:Long,q5:Long,q6:Long,q7:Long Field q8:Long,q9:Long,qa:Long,qb:Long Field qc:Long,qd:Long,qe:Long,qf:Long Field th32MemoryBase:Int Field th32AccessKey:Int End Type Extern "Win32" Function WinExec(lpCmdLine:Byte Ptr,nCmdShow:Int) Function CreateToolhelp32Snapshot:Int(lFlags:Int, lProcessID:Int) Function Process32First(hSnapShot:Int, uProcess:Byte Ptr) Function Process32Next(hSnapShot:Int, uProcess:Byte Ptr) Function CloseHandle(hPass:Int) End Extern Local p:PROCESSENTRY32=New PROCESSENTRY32 p.dwSize=SizeOf(processentry32) Local h:Int=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0) process32First(h,p) DebugLog "szExeFile="+String.FromCString(Varptr p.szExeFile) While process32Next(h,p) DebugLog " szExeFile="+String.FromCString(Varptr p.szExeFile) Wend Note the need to declare the arguments in extern functions as type byte ptr to correctly pass the bmx object as a struct. |
| ||
Cool, this seems to be working perfectly. I have a question though, is there any way that I could use an array for the padding instead of several Long fields? I tried to do it like...... Field szExeFile:Byte Field szExeFileArray:Byte[MAX_PATH - 1] But the SizeOf() for the resulting structure is only 52 instead of 304. I suspect this is because the array does not really allocate memory for each slot but rather is a dynamic one. So it seems there's no way to do the padding with an array... |