Page 3 of 4
VOXporter - Icon (?naming?) problem
Posted: Tue Jul 10, 2018 4:29 pm
by Karl-Heinz
Hi Wolfgang,
IMHO PCall() and PCallNative() are needed only for code that needs to be compatible to VO.
Yes, as i mentioned above, that´s the reason why i´ll use #ifdef __XSHARP__ . VO uses Pcall and X# Pcallnative, so there´s no need to code additional typed functions.
But at least in my VO projects there are really a lot of such calls - in the project where I'm currently working there are 190 PCall() calls.
puuh, that´s a lot. My number is 48, but to add the #ifdef stuff is more or less only a -concentrated of course- copy and paste job .
regards
Karl-Heinz
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 7:25 am
by wriedmann
Hi Karl-Heinz,
I have now updated the docs page, and hope that is is now clear:
https://docs.xsharp.it/doku.php?id=vo_to_net:pcall
I have taken your code as sample, and have added a version using a delegate too:
Code: Select all
delegate RtlGetVersionDelegate( struOS as _winOSVERSIONINFOEX) as dword
function GetRealOsVersionDelegate( dwMajor ref dword , dwMinor ref dword , dwBuild ref dword ) as logic pascal
local struOS is _winOSVERSIONINFOEX
local hFunc as ptr
local oFunc as RtlGetVersionDelegate
local lOk := false as logic
if ( hFunc := GetProcAddress( GetModuleHandle( String2Psz ("Ntdll") ) , String2Psz ( "RtlGetVersion" ))) != NULL_PTR
struOS.dwOSVersionInfoSize:= _SIZEOF ( _WINOSVERSIONINFOEX )
oFunc := ( RtlGetVersionDelegate ) Marshal.GetDelegateForFunctionPointer( hFunc, TypeOf( RtlGetVersionDelegate ) )
if oFunc:Invoke( @struOS ) == 0
dwMajor := struOS.dwMajorVersion
dwMinor := struOS.dwMinorVersion
dwBuild := struOS.dwBuildNumber
lOk := true
endif
endif
return lOk
Unfortunately I'm not able to compile your PCall-Sample, it gives the following errors:
error XS0246: The type or namespace name '__GetRealOsVersion' could not be found (are you missing a using directive or an assembly reference?) 31,16 Start.prg PCallTest
error XS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('__GetRealOsVersion') 31,16 Start.prg PCallTest
error XS0266: Cannot implicitly convert type 'void*' to '__GetRealOsVersion*'. An explicit conversion exists (are you missing a cast?) 35,16 Start.prg PCallTest
Please find my test application attached here.
Wolfgang
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 8:26 am
by Chris
Hi Wolfgang,
You just need to enable the /vo7 compiler option (Resolve function pointers to PTR) and it should work!
Chris
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 8:32 am
by wriedmann
Hi Chris,
You just need to enable the /vo7 compiler option (Resolve function pointers to PTR) and it should work
It was /VO6, and it works now, thank you very much!
Will add it also to the documentation page (that is currently the most changed one <g>)-
Wolfgang
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 10:45 am
by robert
Guys,
Maybe this is a small example that shows how it works with PCall.
Please note that no String2psz() is needed anymore in the PCall because the .Net runtime takes care of that. Also the DLL prototypes now use STRING and ANSI, so the .Net runtime takes care of the converison as well.
Code: Select all
//
// compile with options: /dialect:vo /r:xsharp.core.dll /r:xsharp.vo.dll /vo6 /unsafe
// can compile with AnyCPU as long as you use the X# runtime
//
_DLL FUNCTION LoadLibrary( lpLibFileName AS STRING ) AS PTR PASCAL:KERNEL32.LoadLibraryA ANSI
_DLL FUNCTION FreeLibrary( hModule AS PTR ) AS VOID PASCAL:KERNEL32.FreeLibrary
_DLL FUNCTION GetProcAddress( hModule AS PTR, lpProcName AS STRING ) AS PTR PASCAL:KERNEL32.GetProcAddress ANSI
FUNCTION MyMessageBox( hOwner AS PTR, cMessage AS STRING, cMessage2 AS STRING, nOption AS DWORD) AS DWORD
RETURN 0
FUNCTION Start() AS VOID
LOCAL hModule AS PTR
LOCAL hFunc AS MyMessageBox PTR
hModule := LoadLibrary( "user32.dll" )
hFunc := GetProcAddress( hModule, "MessageBoxA" )
? "MessageBox() returns", PCall( hFunc, NULL, "Hello from XSharp", "PCall() From XSharp", 3 )
FreeLibrary( hModule )
RETURN
The compiler generates a delegate from the MyMessageBox prototype (C# syntax, because ILSpy in X# mode does not show the special $ characters in the names)
Code: Select all
internal unsafe delegate uint $PCall$Start$0(void* hOwner, string cMessage, string cMessage2, uint nOption);
Similar code will be generated for every PCall.
And a special method to request the delegate from the function pointer. If you have more than one PCall then this method will be reused:
Code: Select all
internal static T $PCallGetDelegate<T>(IntPtr p)
{
return (T)(object)Marshal.GetDelegateForFunctionPointer(p, typeof(T));
}
And the relevant code in the Start() function looks like this:
Code: Select all
public unsafe static void Start()
{
void* hModule = LoadLibrary("user32.dll");
IntPtr hFunc2 = (IntPtr)GetProcAddress(hModule, "MessageBoxA");
Functions.QOut("MessageBox() returns", $PCallGetDelegate<$PCall$Start$0>(hFunc2)(null, "Hello from XSharp", "PCall() From XSharp", 3u));
FreeLibrary(hModule);
hFunc2 = (IntPtr)(void*)null;
}
And remember: if you think this is difficult to understand, it was even more difficult to implement this. But it works !
Robert
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 11:02 am
by wriedmann
Hi Robert,
thank you very much for this explanation!
After all the messages in this thread und some experiments with the delegate version this is now clear to me (and I hope to others too).
I have updated not only the PCall() article in the wiki, but also the article about delegates.
Wolfgang
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 11:46 am
by Karl-Heinz
Hi Wolfgang,
1. i imported your PCallTest app.
2. removed your XSRVOWin32APILibrary.dll reference and added VulcanVOWin32APILibrary.dll instead.
3. checked the VO/6 setting as Chris mentioned.
But i receive errors that the api funcs GetModuleHandle() and getprocadress() are not found:
e.g.
error XS0103: The name 'GetProcAddress' does not exist in the current context
I´ve tried it with:
VulcanVOWin32APILibrary.Functions.GetModuleHandle ( String2Psz ("Ntdll") )
but that throws the error:
error XS1503: Argument 1: cannot convert from 'XSharp.__Psz' to 'System.IntPtr'
any idea what´s wrong ?
Maybe i need your "special" XSRVOWin32APILibrary.dll ?
regards
Karl-Heinz
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 11:56 am
by wriedmann
Hi Karl-Heinz,
my "special" library has only a few changes:
- it is compiled with X# instead of Vulcan
- it does not uses includes anymore, but the includes DLL
I have now removed the X# runtime, added the Vulcan runtime and replaced my special Win32API dll by the standard one from Vulcan 4, and now it compiles.
Wolfgang
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 2:49 pm
by Chris
Hi Karl-Heinz,
The issues that you were seeing were because you used the X# runtime as references in your test app, but also used vulcan's VulcanWinAPI dll, which has references to the vulcan runtime dlls. So for now, until we release the X# SDK dlls that you can use with the X# runtime, if you need to use any vulcan SDK dll, please also use the vulcan rutnime dlls as well. That should take care of the error messages.
Chris
VOXporter - Icon (?naming?) problem
Posted: Wed Jul 11, 2018 2:56 pm
by wriedmann
Hi Chris, hi Karl-Heinz,
I have not tested the other VO class libraries, but the Win32SDK library and also the System classes compile happily with the X# compiler and the X# runtime:
- system_classes.png (5.18 KiB) Viewed 537 times
- win32apilib.png (5.2 KiB) Viewed 537 times
I've done that because I have used them in my WinForms application AlpiLog, and I have that one running in testing mode using the X# runtime.
Wolfgang