Thanks for the superb help Florent. The BSTR and other oleaut functions were the cure!
------------------
Ron
Announcement
Collapse
No announcement yet.
Calling a PowerBASIC DLL from C
Collapse
X
-
Guest replied
-
hi ron
the reason you are getting gpfs is because c does not natively
use bstrs (pb dynamic strings). since you can't change the dll
to use asciiz you'll need to handle bstrs from c as in the
following example. there was a long discussion on that subject
at http://www.powerbasic.com/support/pb...ead.php?t=2191
here's some example code that shows how to handle bstrs from
c and pass them to pbdll
Code:// c code #include <windows.h> #include <stdio.h> #include <oleauto.h> typedef int __stdcall lpfncalldll( int dbnumber, bstr dbname, int &prompt ); int __cdecl main( int argc, char *argv[], char *envp[] ) { hmodule hlib; lpfncalldll* lpcalldll; bstr bstring; char *chdsn; int prompt; int lreturn; hlib = loadlibrary( "mydll.dll" ); if ( hlib == null ) { printf( "could not load mydll.dll" ); return false; } lpcalldll = (lpfncalldll*)getprocaddress( hlib, "myfunction" ); if ( lpcalldll == null ) { freelibrary( hlib ); return false; } chdsn = "driver=sql server;server=devtestserver;database=db1;uid=dbuser;pwd=pwrd"; /* use ole strings */ bstring = sysallocstringbytelen( chdsn, strlen(chdsn) ); if ( bstring==null ) { printf( "could not allocate string" ); return false; } prompt = 123; lreturn = lpcalldll( 1, bstring, prompt ); if ( lreturn != 0 ) printf( "function returned %d", lreturn ); /* ole string must be freed afer use */ sysfreestring( bstring ); freelibrary( hlib ); return true; } ------------- 'basic code #compile dll #include "win32api.inc" function myfunction alias "myfunction" ( byval ldbnumber as long, byval sdbname as string, byref lprompt as long ) export as long open "c:\temp\rp_testdll.log" for append as #1 print #1, $crlf;"ldbn:"; ldbnumber, " dbname: "; sdbname;"!"," lprompt:";lprompt close 1 function = 199 end function function libmain(byval hinstance as long, _ byval fwdreason as long, _ byval lpvreserved as long) export as long select case fwdreason case %dll_process_attach libmain = 1 'success! exit function case %dll_process_detach libmain = 1 'success! exit function case %dll_thread_attach libmain = 1 'success! exit function case %dll_thread_detach libmain = 1 'success! exit function end select end function
byval sdbname as string you'd need to declare the function
prototype in c as:
typedef int __stdcall lpfncalldll( int dbnumber, bstr &dbname, int &prompt );
[this message has been edited by florent heyworth (edited august 19, 2000).]
Leave a comment:
-
Calling a PowerBASIC DLL from C
I am attempting to call a PB/DLL created DLL from C. I have no
problems with Asciiz strings or numerics when the function parameter uses BYVAL.
The following is the "test" function I am using. Some functions in the DLL use PB
dynamic (variable length) strings and numerics passed by reference. The DLL is not
mine so I can't change its functions.
When i run the C program the first parameter gets logged to the file just fine, but
the 2nd and 3rd parameters do not make it. A protection fault is raised.
Here's what currently gets logged by the PB Dll:
lDBN: 1 lDBName: ! lPrompt:
lDBN: 1 lDBName: ! lPrompt:
lDBN: 1 lDBName: ! lPrompt:
Code:'[b]RP_TEST.DLL code[/b] Function RP_TestDLL Alias "RP_TestDLL"(ByVal lDBNumber As Long, _ ByVal lDBname As String, _ lPrompt As Long) Export As Long Open "D:\LCC\Sqltest\RP_TestDLL.Log" For Append As #1 Print #1, $CrLf;"lDBN:"; lDBNumber, " lDBName: "; lDBName;"!"," lPrompt:";lPrompt Close 1 Function = 199 End Function
Code://[b]TestPBDll.C[/b] #include <stdio.h> #include <stdlib.h> #include <string.h> #include <win.h> typedef int __stdcall RP_TestDLL( int lDBNumber, CHAR* lDBname, int &Prompt ); int main(int argc,char *argv[]) { DWORD rc=0; CHAR dbn[128]; RP_TestDLL* pRP_TestDLL; HMODULE hRPDll; pRP_TestDLL = (RP_TestDLL* ) GetProcAddress(hRPDll,"RP_TestDLL"); hRPDll = LoadLibrary("RP_Test.dll"); printf("Loaded DLL: %d\r\n",hRPDll ); if (hRPDll == NULL) printf( "hRPDll = Null\r\n"); else { sprintf( dbn, "DRIVER=SQL Server;server=DevTestServer;database=DB1;uid=dbuser;pwd=pwrd\0"); printf ("Before Calling RP_TestDLL - pRP_TestDLL: %d\r\n", pRP_TestDLL ); rc = pRP_TestDLL(1, dbn, 123 ); FreeLibrary(hRPDll); } printf("Done!\r\n"); return 0; {
------------------
Ron
[This message has been edited by Ron Pierce (edited August 19, 2000).]Tags: None
Leave a comment: