VOXporter - Icon (?naming?) problem

This forum is meant for questions and discussions about the X# language and tools
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

VOXporter - Icon (?naming?) problem

Post 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
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

VOXporter - Icon (?naming?) problem

Post 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
Attachments
PCallTest.zip
(1.75 KiB) Downloaded 74 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4913
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

VOXporter - Icon (?naming?) problem

Post by Chris »

Hi Wolfgang,

You just need to enable the /vo7 compiler option (Resolve function pointers to PTR) and it should work!

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

VOXporter - Icon (?naming?) problem

Post 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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
robert
Posts: 4522
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

VOXporter - Icon (?naming?) problem

Post 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
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

VOXporter - Icon (?naming?) problem

Post 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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

VOXporter - Icon (?naming?) problem

Post 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
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

VOXporter - Icon (?naming?) problem

Post 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.
PCallTest.zip
(1.73 KiB) Downloaded 73 times
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4913
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

VOXporter - Icon (?naming?) problem

Post 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
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

VOXporter - Icon (?naming?) problem

Post 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
system_classes.png (5.18 KiB) Viewed 548 times
win32apilib.png
win32apilib.png (5.2 KiB) Viewed 548 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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Post Reply