Replies: 32 comments 80 replies
-
There is code in CM3 to do dynamic loading. I know it's in there because CM3 used to do a lot of it. I am not sure what it is you are trying to do and I can't necessarily answer all your questions (because I don't really do these things much), but let me just say a few things... Like C++ (actually even more than C++), Modula-3 programs generally expect to have a runtime system running all the time, doing things like garbage collection and helping with threading. It's not generally what you want to make CM3 generate a .a or .so and link it with a C program. It's not impossible to do it that way, but by far the easier way is to let the Modula-3 part of your program "be in control" (handle startup and shutdown) and call out to C and run the GC and whatever else it needs to do. In order to link with a C library, you need to provide a .i3 that gives the signature of the C routines and mark them <EXTERNAL>. I have given examples of this in other threads. Then add the -l to the link command in cm3.cfg. I find the easiest way to call M3 from C is to do the above and then pass the M3 routines as PROCEDURE references into the C (declare them as C functions in C). It's very easy, and I have examples that I can share if you're interested. I don't think I have gone through the work to add this to CM3 itself yet, although it is on my todo list. In our system, M3 was doing the basic runtime and comms libraries between modules, including threading and coroutines (the coroutine lib in m3core came from this project) and then called out to C "implementations" of the various modules. Because I was the chief programmer on the project, but the team didn't want to learn Modula-3 (plus we had existing implementations in C of the various bits and pieces). Their loss---but actually it wasn't much of a loss for the project, because C was good for the "bits and pieces" and M3 was perfect for the infrastructure. Unfortunately the project was canceled later (for unrelated reasons), but I still have all the code and have an approval to add it to CM3 at some unspecified future date. If you really want to get deep into this, expect to have to learn about RT0.i3 and other "wizard" interfaces. There's quite a lot of stuff going on in the M3 runtime if you want to use all the language's features together with dynamic loading. The code should be all there but I doubt anyone has used it for a long time. Critical Mass did the work required to add types at runtime and such things. That's really nontrivial and was a lot of work for them to do, because the original SRC implementation didn't have that capability. It's easiest to go the SRC way and have all types known at compile time, but of course you may not be satisfied with that. |
Beta Was this translation helpful? Give feedback.
-
I have a function like this: I tried to pass TEXT directly like this:
But it doesn't work. I have read the interface M3ToC but don't know which functions to use yet. |
Beta Was this translation helpful? Give feedback.
-
how to translate |
Beta Was this translation helpful? Give feedback.
-
On 1/12/23 13:00, tn1997tn wrote:
i have troubles wrapping |char_star_star| as |array of text|, how to convert |array of text| to |char_star_star|?
Modula-3's TEXT values are higher-level than C's strings:
- Importantly for what your want to do, the machine-level
representation is different.
- You don't allocate space for them yourself.
- you don't free them either.
- They are functional, not imperative.
- Nothing like a buffer overrun can happen.
(* ARRAYs can suffer buffer overruns, but those will be
detected at runtime, unless you use a compiler option
to disable what that language mandates. Being
functional, they can't happen to TEXTs at all.*)
Functional means that they don't get altered in place. So
VAR A, B, C: TEXT;
..
A := B & C;
does not Alter either B or C, and you can continue to use
variables B and C with their original values, the way
scalar arithmetic almost always works, i.e. X := Y + Z.
This makes routine handling of character strings a lot easier
to code, but you can't assume ARRAY OF TEXT is equivalent to char**.
None of the above is true when, instead of using TEXT, you write
UNSAFE M3 code to manipulate C's representation.
If you want to receive an array of C strings and use unsafe code
to convert it to M3 types, something like this:
UNSAFE MODULE ...
IMPORT M3toC;
IMPORT Ctypes
...
CONST PrettyLarge = 16_FFFFFF;
TYPE StringsRef = UNTRACED REF ARRAY [ 0 .. PrettyLarge ] OF Ctypes.char_star;
(* Here ------------------------------------^, you lose M3's type safety, as
this array type is declared much larger than its values will actually
be, so you are on your own recognizance not to overrun it, just as you
would be in C.
*)
...
VAR S : Strings : StringsRef := (* However you get the char_star_star value *)
...
S [ I ] will access the Ith element of S and M3toC.CopyStoT ( S [ I ] ) will get
it converted to a M3 TEXT, which you can store anywhere, and it will be safe
from deallocation,, until you have no copies of it.
You can't just map the C array to an M3 open array (ARRAY OF), because that
has a different representation that is necessary to (among other things) check
buffer overruns. To convert to an open array, while leaving the individual
strings still in C representation:
TYPE SafeStringsRef = REF ARRAY OF Ctypes.char_star
(* Count the strings: *)
N := 0;
WHILE S ^ [ N ] # NIL (* The C null pointer that terminates the list of strings. *)
DO INC ( N )
END (* WHILE *);
(* Allocate your own overrun-safe open array, exactly the right size: *)
SafeS := NEW ( SafeStringsRef , N )
(* Copy the C strings with a whole-array assignment: *)
SafeS ^ := SUBARRAY ( S ^ , 0 , N )
Or copy the strings one at a time, converting each to a TEXT,
TYPE SafeTextsRef = REF ARRAY OF TEXT:
...
(* Having counted the strings as above: *)
(* Allocate an open array of TEXTs: *)
SafeT := NEW ( SafeTextsRef , N )
(* Copy the strings, converting them to safe TEXTs. *)
FOR I := 0 TO LAST ( SafeT ^ )
DO
SafeT ^ [ I ] := M3toC . CopyStoT ( S ^ [ I ] )
END (* FOR *)
What is the single most common kind of exploitable security
vulnerability? Buffer overruns. And the C/C++ type system
is helpless to catch them, because it almost always (sizeof,
if the size is static, being the exception) insists on immediately
forgetting whether a pointer points to a single thing or an
array of them, and if the latter, both its lower and upper bounds.
… —
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNAAOOWGNS6HD5TGYWTWSBIEFANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
have a look at these two c functions:
how to accurately translate them? this is my current translation: TinyFileDialogsC.i3
TinyFileDialogs.i3
TinyFileDialogs.m3
as you can see, i want to make it to easy to use as possible, so i wrapped |
Beta Was this translation helpful? Give feedback.
-
m3makefile
|
Beta Was this translation helpful? Give feedback.
-
The single character strings look OK to me, although in general,
I would suggest using CopyTtoS and FreeCopiesS instead of SharedTtoS
and FreeSharedS. The latter should work fine if you are sure the C
functions won't deallocate the string, but it costs very little to
do the copy, and it prevents certain catastrophic bugs without having
to do any vetting.
If the C dialect makes char unsigned, then the integer function results
should be Ctypes.char_star. If signed, then it should be UNTRACED REF Ctypes.signed_char,
which is UNTRACED REF [-16_7F-1..16_7F]. I suspect your C char is signed, since you
used Ctypes.int_star. If there were a Ctypes.signed_char_star, that would be what
to use, but I don't see it declared anywhere in m3core or libm3. Ctypes would
have been written when Various C dialects that did char signedness were common.
As for not using a pointer to int, a little background is needed.
Most (all?) the programming language books assert the principle that
a high-level language's type system abstracts away from the machine-
level bit representations of values. But then we see a lot of languages
that violate this for different integerish types, by giving different
representations different high-level types, which in turn requires many
pages of rules about type conversions, implicit and/or explicit. And
if you write code where you must think about overflows, boundary values,
etc., as is necessary to avoid security holes, it often gets very
complicated just to write a simple arithmetic expression.
Modula-3, mostly, follows the principle by having subranges as the
high-level types for different ranges, leaving representation to the
implementation. This is higher-level and simplifies a lot of things.
But when you start matching different languages' types, you have to
think at the lowest common level. For this, you need inside information
about the Me implementation, not specified by the language. Specifically,
for these examples, you need to know that the CM3 compiler (and all its
predecessors, I believe) stores memory scalar values in the smallest
of 8, 16, 32, or 64 bits that will hold the range.
So Ctypes.int, declared as [-16_7fffffff-1 .. 16_7fffffff] is the subrange
that abstractly contains the full 32-bit signed range, as per Modula-3, and
also occupy a 32-bit sized and aligned word, as per CM3. That is what M3-
compiled code will believe the returned pointer points to. I am sure that is
not what your C code will return a pointer to.
(BTW, when you match C int Ctypes.int, be sure your C int is 32 bits.)
Once you (in M3 code) dereference the value returned, you can freely copy
it around among various subranges of INTEGER without worrying about
explicit or implicit type conversions. The language will either do any size
conversions, or give runtime or compile time errors, if a value won't fit.
The same goes for using in arithmetic operations with other INTEGER subranges.
On a predictably relevant tangent, don't fall prey to an almost universal
misinterpretation of BITS FOR. It applies *only* to array elements and
fields of records and objects and nowhere else. That includes not applying
to formal parameters or function results. Of course if you pass a whole
record or array, it does apply to its components. I can't think how the
language could be any more explicit, but it gets missed over and over.
Rewording suggestions are welcome.
Stay tuned.
…On 1/12/23 23:30, tn1997tn wrote:
have a look at these two c functions:
|char * tinyfd_openFileDialog( char const * aTitle, /* NULL or "" */ char const * aDefaultPathAndFile, /* NULL or "" */ int aNumOfFilterPatterns , /* 0 (2 in the following example) */ char const * const * aFilterPatterns, /* NULL or char const * lFilterPatterns[2]={"*.png","*.jpg"}; */ char const * aSingleFilterDescription, /* NULL or "image files" */ int aAllowMultipleSelects ) ; /* 0 or 1 */ /* in case of multiple files, the separator is | */ /* returns NULL on cancel */ char * tinyfd_colorChooser( char const * aTitle, /* NULL or "" */ char const * aDefaultHexRGB, /* NULL or "#FF0000" */ unsigned char const aDefaultRGB[3] , /* unsigned char lDefaultRGB[3] = { 0 , 128 , 255 }; */ unsigned char aoResultRGB[3] ) ; /* unsigned char lResultRGB[3]; */ /* returns the hexcolor as a string "#FF0000" */ /* aoResultRGB also contains the result */ /* aDefaultRGB is used only if aDefaultHexRGB is NULL */ /* aDefaultRGB and aoResultRGB can be the same array */ /* returns NULL on cancel */ |
how to accurately translate them?
this is my current translation:
TinyFileDialogsC.i3
|<*EXTERNAL tinyfd_openFileDialog*> PROCEDURE tinyfd_openFileDialog(aTitle: char_star; aDefaultPathAndFile: char_star; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: char_star; aAllowMultipleSelects: int): int_star; <*EXTERNAL tinyfd_colorChooser*> PROCEDURE tinyfd_colorChooser(aTitle: char_star; aDefaultHexRGB: char_star; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
TinyFileDialogs.i3
|PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
TinyFileDialogs.m3
|PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultPathAndFile), s3 = SharedTtoS(aSingleFilterDescription) DO TRY res:= TinyFileDialogsC.tinyfd_openFileDialog(s1, s2, aNumOfFilterPatterns, aFilterPatterns, s3, aAllowMultipleSelects); FINALLY FreeSharedS(aTitle, s1); FreeSharedS(aDefaultPathAndFile, s2); FreeSharedS(aSingleFilterDescription, s3); RETURN res END END END tinyfd_openFileDialog; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultHexRGB) DO TRY res:= TinyFileDialogsC.tinyfd_colorChooser(s1, s2, aDefaultRGB, aoResultRGB); FINALLY FreeSharedS(aTitle, s1);
FreeSharedS(aDefaultHexRGB, s2); RETURN res END END END tinyfd_colorChooser; |
as you can see, i want to make it to easy to use as possible, so i wrapped |char_star| to TEXT like this. but i'm currently stuck at
|char_star_star|. if i can map it to |array of text| then the api will be much easier to use i think.
—
Reply to this email directly, view it on GitHub <#1140 (comment)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNHIOXWMTMIDQUPKK7LWSDSARANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
My earlier post about arrays of strings was for the reverse
direction. This is for passing from Modulla-3 to C.
The actual contents of M3 arrays are pretty much
the same as C arrays, but the way(s) of allocating them
and denoting the elementcounts are different.
Here is a way to pass from M3 to C, keeping all
the representation differences combined to the wrapper and
typing everything in the natural Modula-3 way outside. I
am leaving out all the other parameters and the function
result. I am also inferring from the C prototype that parameter
ANumOfFilterPatterns gives the element count of AFilterPatterns
to the C code.
Some C code may do it otherwise, e.g., with a null
pointer in an extra array element, which you would have to
adapt to, including allocating CArr with space for it.
Note that the null pointer in M3 is named NIL, not NULL.
The Wrapper:
TYPE CStringArrRef = REF ARRAY OF Ctypes.char_star;
PROCEDURE |tinyfd_openFileDialog ( FilterPatterns: ARRAY OF TEXT) =
VAR Ct: INTEGER;
VAR CArr : CStringArrRef;
BEGIN
Ct := NUMBER (FilterPatterns);
CArr := NEW (CStringArrRef, Ct)
FOR I := 0 TO LAST ( CArr)
DO CArr ^ [I] := M3ToC.CopyTtoS (FilterPatterns[I])
END;
TRY DialogC.||||tinyfd_openFileDialog(Ct, ADR(CArr^[0]);
FINALLY
FOR I := 0 TO LAST (CArr)
DO M3ToC.FreeCopiedS(CArr^[I])
END
CArr := NIL (* Not really necessary, but illustrative. *)
END
END ||tinyfd_openFileDialog;
|||||Now you can construct your strings entirely using natural M3
types, inside a safe module, and just pass to the wrapper.
You can pass a fixed array, an open array, or a SUBARRAY of either
to the open array formal FilterPatterns.
When passing the address of a Modula-3 open array A to C code,
You must pass ADR(A[0]), not ADR(A). The latter is the address
of dope used behind the scenes for the element count etc.
…On 1/12/23 23:30, tn1997tn wrote:
have a look at these two c functions:
|char * tinyfd_openFileDialog( char const * aTitle, /* NULL or "" */ char const * aDefaultPathAndFile, /* NULL or "" */ int aNumOfFilterPatterns , /* 0 (2 in the following example) */ char const * const * aFilterPatterns, /* NULL or char const * lFilterPatterns[2]={"*.png","*.jpg"}; */ char const * aSingleFilterDescription, /* NULL or "image files" */ int aAllowMultipleSelects ) ; /* 0 or 1 */ /* in case of multiple files, the separator is | */ /* returns NULL on cancel */ char * tinyfd_colorChooser( char const * aTitle, /* NULL or "" */ char const * aDefaultHexRGB, /* NULL or "#FF0000" */ unsigned char const aDefaultRGB[3] , /* unsigned char lDefaultRGB[3] = { 0 , 128 , 255 }; */ unsigned char aoResultRGB[3] ) ; /* unsigned char lResultRGB[3]; */ /* returns the hexcolor as a string "#FF0000" */ /* aoResultRGB also contains the result */ /* aDefaultRGB is used only if aDefaultHexRGB is NULL */ /* aDefaultRGB and aoResultRGB can be the same array */ /* returns NULL on cancel */ |
how to accurately translate them?
this is my current translation:
TinyFileDialogsC.i3
|<*EXTERNAL tinyfd_openFileDialog*> PROCEDURE tinyfd_openFileDialog(aTitle: char_star; aDefaultPathAndFile: char_star; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: char_star; aAllowMultipleSelects: int): int_star; <*EXTERNAL tinyfd_colorChooser*> PROCEDURE tinyfd_colorChooser(aTitle: char_star; aDefaultHexRGB: char_star; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
TinyFileDialogs.i3
|PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
TinyFileDialogs.m3
|PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultPathAndFile), s3 = SharedTtoS(aSingleFilterDescription) DO TRY res:= TinyFileDialogsC.tinyfd_openFileDialog(s1, s2, aNumOfFilterPatterns, aFilterPatterns, s3, aAllowMultipleSelects); FINALLY FreeSharedS(aTitle, s1); FreeSharedS(aDefaultPathAndFile, s2); FreeSharedS(aSingleFilterDescription, s3); RETURN res END END END tinyfd_openFileDialog; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultHexRGB) DO TRY res:= TinyFileDialogsC.tinyfd_colorChooser(s1, s2, aDefaultRGB, aoResultRGB); FINALLY FreeSharedS(aTitle, s1);
FreeSharedS(aDefaultHexRGB, s2); RETURN res END END END tinyfd_colorChooser; |
as you can see, i want to make it to easy to use as possible, so i wrapped |char_star| to TEXT like this. but i'm currently stuck at
|char_star_star|. if i can map it to |array of text| then the api will be much easier to use i think.
—
Reply to this email directly, view it on GitHub <#1140 (comment)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNHIOXWMTMIDQUPKK7LWSDSARANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
From the output of m3swig, I found it's using the same approach as my code above but there are a few disagreements in types mapping. The code produced by m3swig also doesn't compile. |
Beta Was this translation helpful? Give feedback.
-
See below, two places.
On 1/14/23 19:06, Rodney Bates wrote:
My earlier post about arrays of strings was for the reverse
direction. This is for passing from Modulla-3 to C.
The actual contents of M3 arrays are pretty much
the same as C arrays, but the way(s) of allocating them
and denoting the elementcounts are different.
Here is a way to pass from M3 to C, keeping all
the representation differences combined to the wrapper and
typing everything in the natural Modula-3 way outside. I
am leaving out all the other parameters and the function
result. I am also inferring from the C prototype that parameter
ANumOfFilterPatterns gives the element count of AFilterPatterns
to the C code.
Some C code may do it otherwise, e.g., with a null
pointer in an extra array element, which you would have to
adapt to, including allocating CArr with space for it.
Note that the null pointer in M3 is named NIL, not NULL.
The Wrapper:
TYPE CStringArrRef = REF ARRAY OF Ctypes.char_star;
I suppose the above could be UNTRACED, then replace the CArr := NIL
below by DISPOSE(CArr).
I don't see much preference between letting it be garbage-colleced,
as originally, or explicitly deallocated. This code is necessarily
already UNSAFE anyway, and it prevents any copies of the array pointer
copies from escaping. UNTRACED could possibly be slightly faster.
Unauthorized leak of inside implementation info: CM3 just uses malloc
for the untraced heap.
PROCEDURE |tinyfd_openFileDialog ( FilterPatterns: ARRAY OF TEXT) =
VAR Ct: INTEGER;
VAR CArr : CStringArrRef;
BEGIN
Ct := NUMBER (FilterPatterns);
CArr := NEW (CStringArrRef, Ct)
FOR I := 0 TO LAST ( CArr)
DO CArr ^ [I] := M3ToC.CopyTtoS (FilterPatterns[I])
END;
TRY DialogC.||||tinyfd_openFileDialog(Ct, ADR(CArr^[0]);
|
Given the EXTERNAL declaration you have in TinyFileDialogsC.i3, the
above line would have to be:
| TRY DialogC.||||tinyfd_openFileDialog(Ct, LOOPHOLE (ADR(CArr^[0]), Ctypes.char_star_star));
| since that is the way aFilterPatterns is typed.
… | FINALLY
FOR I := 0 TO LAST (CArr)
DO M3ToC.FreeCopiedS(CArr^[I])
END
CArr := NIL (* Not really necessary, but illustrative. *)
END
END ||tinyfd_openFileDialog;
|||||Now you can construct your strings entirely using natural M3
types, inside a safe module, and just pass to the wrapper.
You can pass a fixed array, an open array, or a SUBARRAY of either
to the open array formal FilterPatterns.
When passing the address of a Modula-3 open array A to C code,
You must pass ADR(A[0]), not ADR(A). The latter is the address
of dope used behind the scenes for the element count etc.
On 1/12/23 23:30, tn1997tn wrote:
>
> have a look at these two c functions:
>
> |char * tinyfd_openFileDialog( char const * aTitle, /* NULL or "" */ char const * aDefaultPathAndFile, /* NULL or "" */ int aNumOfFilterPatterns , /* 0 (2 in the following example) */ char const * const * aFilterPatterns, /* NULL or char const * lFilterPatterns[2]={"*.png","*.jpg"}; */ char const * aSingleFilterDescription, /* NULL or "image files" */ int aAllowMultipleSelects ) ; /* 0 or 1 */ /* in case of multiple files, the separator is | */ /* returns NULL on cancel */ char * tinyfd_colorChooser( char const * aTitle, /* NULL or "" */ char const * aDefaultHexRGB, /* NULL or "#FF0000" */ unsigned char const aDefaultRGB[3] , /* unsigned char lDefaultRGB[3] = { 0 , 128 , 255 }; */ unsigned char aoResultRGB[3] ) ; /* unsigned char lResultRGB[3]; */ /* returns the hexcolor as a string "#FF0000" */ /* aoResultRGB also contains the result */ /* aDefaultRGB is used only if aDefaultHexRGB is NULL */ /* aDefaultRGB and aoResultRGB can be the same array */ /* returns NULL on
> cancel */ |
>
> how to accurately translate them?
>
> this is my current translation:
>
> TinyFileDialogsC.i3
>
> |<*EXTERNAL tinyfd_openFileDialog*> PROCEDURE tinyfd_openFileDialog(aTitle: char_star; aDefaultPathAndFile: char_star; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: char_star; aAllowMultipleSelects: int): int_star; <*EXTERNAL tinyfd_colorChooser*> PROCEDURE tinyfd_colorChooser(aTitle: char_star; aDefaultHexRGB: char_star; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
>
> TinyFileDialogs.i3
>
> |PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star; |
>
> TinyFileDialogs.m3
>
> |PROCEDURE tinyfd_openFileDialog(aTitle: TEXT; aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: int; aFilterPatterns: char_star_star; aSingleFilterDescription: TEXT; aAllowMultipleSelects: int): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultPathAndFile), s3 = SharedTtoS(aSingleFilterDescription) DO TRY res:= TinyFileDialogsC.tinyfd_openFileDialog(s1, s2, aNumOfFilterPatterns, aFilterPatterns, s3, aAllowMultipleSelects); FINALLY FreeSharedS(aTitle, s1); FreeSharedS(aDefaultPathAndFile, s2); FreeSharedS(aSingleFilterDescription, s3); RETURN res END END END tinyfd_openFileDialog; PROCEDURE tinyfd_colorChooser(aTitle: TEXT; aDefaultHexRGB: TEXT; aDefaultRGB: unsigned_char_star; aoResultRGB: unsigned_char_star): int_star = VAR res: int_star; BEGIN WITH s1 = SharedTtoS(aTitle), s2 = SharedTtoS(aDefaultHexRGB) DO TRY res:= TinyFileDialogsC.tinyfd_colorChooser(s1, s2, aDefaultRGB, aoResultRGB); FINALLY FreeSharedS(aTitle, s1);
> FreeSharedS(aDefaultHexRGB, s2); RETURN res END END END tinyfd_colorChooser; |
>
> as you can see, i want to make it to easy to use as possible, so i wrapped |char_star| to TEXT like this. but i'm currently stuck at
> |char_star_star|. if i can map it to |array of text| then the api will be much easier to use i think.
>
> —
> Reply to this email directly, view it on GitHub <#1140 (comment)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNHIOXWMTMIDQUPKK7LWSDSARANCNFSM6AAAAAATXWTVR4>.
> You are receiving this because you commented.Message ID: ***@***.***>
>
|
Beta Was this translation helpful? Give feedback.
-
On 1/15/23 11:04, tn1997tn wrote:
tinyfiledialogsRaw.i3
|(******************************************************************************* * This file was automatically generated by SWIG (http://www.swig.org). * Version 4.0.1 * * Do not make changes to this file unless you know what you are doing--modify * the SWIG interface file instead. *******************************************************************************) INTERFACE tinyfiledialogsRaw; IMPORT Ctypes AS C; <* EXTERNAL tinyfd_beep *> PROCEDURE tinyfd_beep (); <* EXTERNAL tinyfd_notifyPopup *> PROCEDURE tinyfd_notifyPopup ( aTitle, aMessage, aIconType: C.char_star; ): C.int; <* EXTERNAL tinyfd_messageBox *> PROCEDURE tinyfd_messageBox ( aTitle, aMessage, aDialogType, aIconType: C.char_star; aDefaultButton: C.int; ): C.int; <* EXTERNAL tinyfd_inputBox *> PROCEDURE tinyfd_inputBox ( aTitle, aMessage, aDefaultInput: C.char_star; ): C.char_star; <* EXTERNAL tinyfd_saveFileDialog *> PROCEDURE tinyfd_saveFileDialog ( aTitle, aDefaultPathAndFile: C.char_star;
aNumOfFilterPatterns: C.int;|
|Swig has typed C int and M3 Ctypes.int as equivalent. Ctypes.int
is declared so it is 32 bits (regardless of whether the M3 target
is 32- or 64-bit). Does this agree with C int in your
dialect/implementation of C? |
… |READONLY aFilterPatterns: char; aSingleFilterDescription: C.char_star; ): C.char_star; <* EXTERNAL tinyfd_openFileDialog *> PROCEDURE tinyfd_openFileDialog ( aTitle, aDefaultPathAndFile: C.char_star; aNumOfFilterPatterns: C.int; READONLY aFilterPatterns: char; aSingleFilterDescription: C.char_star; aAllowMultipleSelects: C.int; ): C.char_star; <* EXTERNAL tinyfd_selectFolderDialog *> PROCEDURE tinyfd_selectFolderDialog ( aTitle, aDefaultPath: C.char_star; ): C.char_star; <* EXTERNAL tinyfd_colorChooser *> PROCEDURE tinyfd_colorChooser ( aTitle, aDefaultHexRGB: C.char_star; VAR aDefaultRGB: (*ARRAY OF*) unsigned char const; VAR aoResultRGB: (*ARRAY OF*) unsigned char; ): C.char_star; END tinyfiledialogsRaw. |
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNESEO2WT54PVPUQEPDWSQU2TANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
A suggestion for improvement of CM3 documentation: keywords reference like FreeBasic. People rarely remember conditional statements but they do remember IF keyword. Lists of keywords, both alphabetical and functional like Freebasic provides is very handy: https://www.freebasic.net/wiki/CatPgFullIndex https://www.freebasic.net/wiki/CatPgFunctIndex CM3 has a list of keywords, but only a list, contains no link to reference of each keyword like FreeBasic: https://www.freebasic.net/wiki/KeyPgIfthen About documentation, you have to learn from FreeBasic a lot. It's not for no reasons FreeBasic is popular. |
Beta Was this translation helpful? Give feedback.
-
It dawned on me that when passing in an array of TEXT by
VALUE (the default) into the wrapper, Modula-3 already
makes a copy. So it wouldn't be necessary to code another
copy in the wrapper. Just convert the TEXT values to
char_star_star in situ.
The wrapper can fully limit how this mutated (mutilated?)
array is used, while the original array in the actual parameter
will keep the TEXT values and protect them from garbage
collection.
This is pretty crude, low-level stuff, but matching different
languages' machine-level representations that are at different
levels is inherently that way. So maybe:
PROCEDURE tinyfd_openFileDialog (FilterPatterns: ARRAY OF TEXT) =
BEGIN
FOR I := 0 TO LAST (FilterPatterns)
DO WITH WFPI = FilterPatterns [I]
DO LOOPHOLE (WFPI, CTypes.char_star) := M3ToC.CopyTtoS (WFPI)
END (*WITH*)
END (*FOR*);
TRY DialogC.tinyfd_openFileDialog
(NUMBER (FilterPatterns),
LOOPHOLE (ADR(FilterPatterns[0]), Ctypes.char_star_star)
)
FINALLY
FOR I := 0 TO LAST (FilterPatterns)
DO WITH WFPI = FilterPatterns [I]
DO M3toC.FreeCopiedS(LOOPHOLE (WFPI, CTypes.char_star)
END (*WITH*)
END (*FOR*);
END (*FINALLY*)
END tinyfd_openFileDialog
…On 1/14/23 19:06, Rodney Bates wrote:
My earlier post about arrays of strings was for the reverse
direction. This is for passing from Modulla-3 to C.
The actual contents of M3 arrays are pretty much
the same as C arrays, but the way(s) of allocating them
and denoting the elementcounts are different.
Here is a way to pass from M3 to C, keeping all
the representation differences combined to the wrapper and
typing everything in the natural Modula-3 way outside. I
am leaving out all the other parameters and the function
result. I am also inferring from the C prototype that parameter
ANumOfFilterPatterns gives the element count of AFilterPatterns
to the C code.
Some C code may do it otherwise, e.g., with a null
pointer in an extra array element, which you would have to
adapt to, including allocating CArr with space for it.
Note that the null pointer in M3 is named NIL, not NULL.
The Wrapper:
TYPE CStringArrRef = REF ARRAY OF Ctypes.char_star;
PROCEDURE |tinyfd_openFileDialog ( FilterPatterns: ARRAY OF TEXT) =
VAR Ct: INTEGER;
VAR CArr : CStringArrRef;
BEGIN
Ct := NUMBER (FilterPatterns);
CArr := NEW (CStringArrRef, Ct)
FOR I := 0 TO LAST ( CArr)
DO CArr ^ [I] := M3ToC.CopyTtoS (FilterPatterns[I])
END;
TRY DialogC.||||tinyfd_openFileDialog(Ct, ADR(CArr^[0]);
FINALLY
FOR I := 0 TO LAST (CArr)
DO M3ToC.FreeCopiedS(CArr^[I])
END
CArr := NIL (* Not really necessary, but illustrative. *)
END
END ||tinyfd_openFileDialog;
|||||Now you can construct your strings entirely using natural M3
types, inside a safe module, and just pass to the wrapper.
You can pass a fixed array, an open array, or a SUBARRAY of either
to the open array formal FilterPatterns.
When passing the address of a Modula-3 open array A to C code,
You must pass ADR(A[0]), not ADR(A). The latter is the address
of dope used behind the scenes for the element count etc.
—
> Reply to this email directly, view it on GitHub <#1140 (comment)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNHIOXWMTMIDQUPKK7LWSDSARANCNFSM6AAAAAATXWTVR4>.
> You are receiving this because you commented.Message ID: ***@***.***>
>
|
Beta Was this translation helpful? Give feedback.
-
It looks like SWIG has just completely punted on the arrays of strings.
It just passes then through, untouched and typed as "char" (notC.char).
But I don't see any problems with the other types.
…On 1/15/23 11:03, tn1997tn wrote:
tinyfiledialogs.m3
|(******************************************************************************* * This file was automatically generated by SWIG (http://www.swig.org). * Version 4.0.1 * * Do not make changes to this file unless you know what you are doing--modify * the SWIG interface file instead. *******************************************************************************) MODULE tinyfiledialogs; IMPORT M3toC; IMPORT tinyfiledialogsRaw; IMPORT Ctypes AS C; PROCEDURE tinyfd_beep () = BEGIN tinyfiledialogsRaw.tinyfd_beep(); END tinyfd_beep; PROCEDURE tinyfd_notifyPopup ( aTitle, aMessage, aIconType: TEXT; ): INTEGER = VAR arg1 : C.char_star; arg2 : C.char_star; arg3 : C.char_star; result: INTEGER; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aMessage); arg3 := M3toC.SharedTtoS(aIconType); result := tinyfiledialogsRaw.tinyfd_notifyPopup(arg1, arg2, arg3); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aMessage,arg2); M3toC.FreeSharedS(aIconType,arg3); RETURN
result; END tinyfd_notifyPopup; PROCEDURE tinyfd_messageBox ( aTitle, aMessage, aDialogType, aIconType: TEXT; aDefaultButton: INTEGER; ): INTEGER = VAR arg1 : C.char_star; arg2 : C.char_star; arg3 : C.char_star; arg4 : C.char_star; result: INTEGER; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aMessage); arg3 := M3toC.SharedTtoS(aDialogType); arg4 := M3toC.SharedTtoS(aIconType); result := tinyfiledialogsRaw.tinyfd_messageBox(arg1, arg2, arg3, arg4, aDefaultButton); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aMessage,arg2); M3toC.FreeSharedS(aDialogType,arg3); M3toC.FreeSharedS(aIconType,arg4); RETURN result; END tinyfd_messageBox; PROCEDURE tinyfd_inputBox ( aTitle, aMessage, aDefaultInput: TEXT; ): TEXT = VAR result : C.char_star; arg1 : C.char_star; arg2 : C.char_star; arg3 : C.char_star; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aMessage); arg3 := M3toC.SharedTtoS(aDefaultInput); result :=
tinyfiledialogsRaw.tinyfd_inputBox(arg1, arg2, arg3); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aMessage,arg2); M3toC.FreeSharedS(aDefaultInput,arg3); RETURN M3toC.CopyStoT(result); END tinyfd_inputBox; PROCEDURE tinyfd_saveFileDialog ( aTitle, aDefaultPathAndFile: TEXT; aNumOfFilterPatterns: INTEGER; READONLY aFilterPatterns: char; aSingleFilterDescription: TEXT; ): TEXT = VAR result : C.char_star; arg1 : C.char_star; arg2 : C.char_star; arg5 : C.char_star; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aDefaultPathAndFile); arg5 := M3toC.SharedTtoS(aSingleFilterDescription); result := tinyfiledialogsRaw.tinyfd_saveFileDialog(arg1, arg2, aNumOfFilterPatterns, aFilterPatterns, arg5); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aDefaultPathAndFile,arg2); M3toC.FreeSharedS(aSingleFilterDescription,arg5); RETURN M3toC.CopyStoT(result); END tinyfd_saveFileDialog; PROCEDURE tinyfd_openFileDialog ( aTitle, aDefaultPathAndFile: TEXT;
aNumOfFilterPatterns: INTEGER; READONLY aFilterPatterns: char; aSingleFilterDescription: TEXT; aAllowMultipleSelects: INTEGER; ): TEXT = VAR result : C.char_star; arg1 : C.char_star; arg2 : C.char_star; arg5 : C.char_star; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aDefaultPathAndFile); arg5 := M3toC.SharedTtoS(aSingleFilterDescription); result := tinyfiledialogsRaw.tinyfd_openFileDialog(arg1, arg2, aNumOfFilterPatterns, aFilterPatterns, arg5, aAllowMultipleSelects); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aDefaultPathAndFile,arg2); M3toC.FreeSharedS(aSingleFilterDescription,arg5); RETURN M3toC.CopyStoT(result); END tinyfd_openFileDialog; PROCEDURE tinyfd_selectFolderDialog ( aTitle, aDefaultPath: TEXT; ): TEXT = VAR result : C.char_star; arg1 : C.char_star; arg2 : C.char_star; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aDefaultPath); result := tinyfiledialogsRaw.tinyfd_selectFolderDialog(arg1, arg2);
M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aDefaultPath,arg2); RETURN M3toC.CopyStoT(result); END tinyfd_selectFolderDialog; PROCEDURE tinyfd_colorChooser ( aTitle, aDefaultHexRGB: TEXT; VAR aDefaultRGB: ARRAY OF unsigned char const; VAR aoResultRGB: ARRAY OF unsigned char; ): TEXT = VAR result : C.char_star; arg1 : C.char_star; arg2 : C.char_star; BEGIN arg1 := M3toC.SharedTtoS(aTitle); arg2 := M3toC.SharedTtoS(aDefaultHexRGB); result := tinyfiledialogsRaw.tinyfd_colorChooser(arg1, arg2, aDefaultRGB, aoResultRGB); M3toC.FreeSharedS(aTitle,arg1); M3toC.FreeSharedS(aDefaultHexRGB,arg2); RETURN M3toC.CopyStoT(result); END tinyfd_colorChooser; BEGIN END tinyfiledialogs. |
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNBZMMGJN6UQ5ODGXMTWSQUW5ANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I have pushed swigm3 to github and tested it against this file. It works
with
swig -java jniw32.i
but not with swig -modula3 jniw32.i since it is not a modula3 interface
file.
It looks like it was designed to interface java to a c header.
What exactly are you trying to do?
To build bindings for m3 you need m3 specific typemaps etc.
Regards Peter
…On Mon, 16 Jan 2023 at 18:39, tn1997tn ***@***.***> wrote:
@demoitem </~https://github.com/demoitem> Please have a look at my jniw32.i,
m3swig always crashed with Assertion failed: b->refcount > 0, file
DOH/base.c, line 42 when latest swig (4.1.1) has no problems.
%module jniw32
%{
%}
//#define JNIEXPORT __declspec(dllexport)
//#define JNIIMPORT __declspec(dllimport)
//#define JNICALL __stdcall
#define JNIEXPORT
#define JNIIMPORT
#define JNICALL
// 'long' is always 32 bit on windows so this matches what jdk expects
typedef long jint;
//typedef __int64 jlong;
typedef long long jlong;
typedef signed char jbyte;
/*
* JNI Types
*/
typedef unsigned char jboolean;
typedef unsigned short jchar;
typedef short jshort;
typedef float jfloat;
typedef double jdouble;
typedef jint jsize;
struct _jobject;
typedef struct _jobject *jobject;
typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;
typedef jobject jweak;
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
struct _jfieldID;
typedef struct _jfieldID *jfieldID;
struct _jmethodID;
typedef struct _jmethodID *jmethodID;
/* Return values from jobjectRefType */
typedef enum _jobjectType {
JNIInvalidRefType = 0,
JNILocalRefType = 1,
JNIGlobalRefType = 2,
JNIWeakGlobalRefType = 3
} jobjectRefType;
/*
* jboolean constants
*/
#define JNI_FALSE 0
#define JNI_TRUE 1
/*
* possible return values for JNI functions.
*/
#define JNI_OK 0 /* success */
#define JNI_ERR (-1) /* unknown error */
#define JNI_EDETACHED (-2) /* thread detached from the VM */
#define JNI_EVERSION (-3) /* JNI version error */
#define JNI_ENOMEM (-4) /* not enough memory */
#define JNI_EEXIST (-5) /* VM already created */
#define JNI_EINVAL (-6) /* invalid arguments */
/*
* used in ReleaseScalarArrayElements
*/
#define JNI_COMMIT 1
#define JNI_ABORT 2
/*
* used in RegisterNatives to describe native method name, signature,
* and function pointer.
*/
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
/*
* JNI Native Method Interface.
*/
struct JNINativeInterface_;
struct JNIEnv_;
typedef const struct JNINativeInterface_ *JNIEnv;
/*
* JNI Invocation Interface.
*/
struct JNIInvokeInterface_;
struct JavaVM_;
typedef const struct JNIInvokeInterface_ *JavaVM;
struct JNINativeInterface_ {
void *reserved0;
void *reserved1;
void *reserved2;
void *reserved3;
jint (JNICALL *GetVersion)(JNIEnv *env);
jclass (JNICALL *DefineClass)
(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
jsize len);
jclass (JNICALL *FindClass)
(JNIEnv *env, const char *name);
jmethodID (JNICALL *FromReflectedMethod)
(JNIEnv *env, jobject method);
jfieldID (JNICALL *FromReflectedField)
(JNIEnv *env, jobject field);
jobject (JNICALL *ToReflectedMethod)
(JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
jclass (JNICALL *GetSuperclass)
(JNIEnv *env, jclass sub);
jboolean (JNICALL *IsAssignableFrom)
(JNIEnv *env, jclass sub, jclass sup);
jobject (JNICALL *ToReflectedField)
(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
jint (JNICALL *Throw)
(JNIEnv *env, jthrowable obj);
jint (JNICALL *ThrowNew)
(JNIEnv *env, jclass clazz, const char *msg);
jthrowable (JNICALL *ExceptionOccurred)
(JNIEnv *env);
void (JNICALL *ExceptionDescribe)
(JNIEnv *env);
void (JNICALL *ExceptionClear)
(JNIEnv *env);
void (JNICALL *FatalError)
(JNIEnv *env, const char *msg);
jint (JNICALL *PushLocalFrame)
(JNIEnv *env, jint capacity);
jobject (JNICALL *PopLocalFrame)
(JNIEnv *env, jobject result);
jobject (JNICALL *NewGlobalRef)
(JNIEnv *env, jobject lobj);
void (JNICALL *DeleteGlobalRef)
(JNIEnv *env, jobject gref);
void (JNICALL *DeleteLocalRef)
(JNIEnv *env, jobject obj);
jboolean (JNICALL *IsSameObject)
(JNIEnv *env, jobject obj1, jobject obj2);
jobject (JNICALL *NewLocalRef)
(JNIEnv *env, jobject ref);
jint (JNICALL *EnsureLocalCapacity)
(JNIEnv *env, jint capacity);
jobject (JNICALL *AllocObject)
(JNIEnv *env, jclass clazz);
jobject (JNICALL *NewObject)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jobject (JNICALL *NewObjectV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jobject (JNICALL *NewObjectA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jclass (JNICALL *GetObjectClass)
(JNIEnv *env, jobject obj);
jboolean (JNICALL *IsInstanceOf)
(JNIEnv *env, jobject obj, jclass clazz);
jmethodID (JNICALL *GetMethodID)
(JNIEnv *env, jclass clazz, const char *name, const char *sig);
jobject (JNICALL *CallObjectMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jobject (JNICALL *CallObjectMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jobject (JNICALL *CallObjectMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
jboolean (JNICALL *CallBooleanMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jboolean (JNICALL *CallBooleanMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jboolean (JNICALL *CallBooleanMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
jbyte (JNICALL *CallByteMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jbyte (JNICALL *CallByteMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jbyte (JNICALL *CallByteMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jchar (JNICALL *CallCharMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jchar (JNICALL *CallCharMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jchar (JNICALL *CallCharMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jshort (JNICALL *CallShortMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jshort (JNICALL *CallShortMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jshort (JNICALL *CallShortMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jint (JNICALL *CallIntMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jint (JNICALL *CallIntMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jint (JNICALL *CallIntMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jlong (JNICALL *CallLongMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jlong (JNICALL *CallLongMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jlong (JNICALL *CallLongMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jfloat (JNICALL *CallFloatMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jfloat (JNICALL *CallFloatMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jfloat (JNICALL *CallFloatMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
jdouble (JNICALL *CallDoubleMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
jdouble (JNICALL *CallDoubleMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
jdouble (JNICALL *CallDoubleMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
void (JNICALL *CallVoidMethod)
(JNIEnv *env, jobject obj, jmethodID methodID, ...);
void (JNICALL *CallVoidMethodV)
(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
void (JNICALL *CallVoidMethodA)
(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
jobject (JNICALL *CallNonvirtualObjectMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jobject (JNICALL *CallNonvirtualObjectMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jobject (JNICALL *CallNonvirtualObjectMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue * args);
jboolean (JNICALL *CallNonvirtualBooleanMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jboolean (JNICALL *CallNonvirtualBooleanMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jboolean (JNICALL *CallNonvirtualBooleanMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue * args);
jbyte (JNICALL *CallNonvirtualByteMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jbyte (JNICALL *CallNonvirtualByteMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jbyte (JNICALL *CallNonvirtualByteMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jchar (JNICALL *CallNonvirtualCharMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jchar (JNICALL *CallNonvirtualCharMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jchar (JNICALL *CallNonvirtualCharMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jshort (JNICALL *CallNonvirtualShortMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jshort (JNICALL *CallNonvirtualShortMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jshort (JNICALL *CallNonvirtualShortMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jint (JNICALL *CallNonvirtualIntMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jint (JNICALL *CallNonvirtualIntMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jint (JNICALL *CallNonvirtualIntMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jlong (JNICALL *CallNonvirtualLongMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jlong (JNICALL *CallNonvirtualLongMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jlong (JNICALL *CallNonvirtualLongMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jfloat (JNICALL *CallNonvirtualFloatMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jfloat (JNICALL *CallNonvirtualFloatMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jfloat (JNICALL *CallNonvirtualFloatMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
jdouble (JNICALL *CallNonvirtualDoubleMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
jdouble (JNICALL *CallNonvirtualDoubleMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
jdouble (JNICALL *CallNonvirtualDoubleMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue *args);
void (JNICALL *CallNonvirtualVoidMethod)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
void (JNICALL *CallNonvirtualVoidMethodV)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
va_list args);
void (JNICALL *CallNonvirtualVoidMethodA)
(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue * args);
jfieldID (JNICALL *GetFieldID)
(JNIEnv *env, jclass clazz, const char *name, const char *sig);
jobject (JNICALL *GetObjectField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jboolean (JNICALL *GetBooleanField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jbyte (JNICALL *GetByteField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jchar (JNICALL *GetCharField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jshort (JNICALL *GetShortField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jint (JNICALL *GetIntField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jlong (JNICALL *GetLongField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jfloat (JNICALL *GetFloatField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
jdouble (JNICALL *GetDoubleField)
(JNIEnv *env, jobject obj, jfieldID fieldID);
void (JNICALL *SetObjectField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
void (JNICALL *SetBooleanField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val);
void (JNICALL *SetByteField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val);
void (JNICALL *SetCharField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jchar val);
void (JNICALL *SetShortField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jshort val);
void (JNICALL *SetIntField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
void (JNICALL *SetLongField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jlong val);
void (JNICALL *SetFloatField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val);
void (JNICALL *SetDoubleField)
(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val);
jmethodID (JNICALL *GetStaticMethodID)
(JNIEnv *env, jclass clazz, const char *name, const char *sig);
jobject (JNICALL *CallStaticObjectMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jobject (JNICALL *CallStaticObjectMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jobject (JNICALL *CallStaticObjectMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jboolean (JNICALL *CallStaticBooleanMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jboolean (JNICALL *CallStaticBooleanMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jboolean (JNICALL *CallStaticBooleanMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jbyte (JNICALL *CallStaticByteMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jbyte (JNICALL *CallStaticByteMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jbyte (JNICALL *CallStaticByteMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jchar (JNICALL *CallStaticCharMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jchar (JNICALL *CallStaticCharMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jchar (JNICALL *CallStaticCharMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jshort (JNICALL *CallStaticShortMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jshort (JNICALL *CallStaticShortMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jshort (JNICALL *CallStaticShortMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jint (JNICALL *CallStaticIntMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jint (JNICALL *CallStaticIntMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jint (JNICALL *CallStaticIntMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jlong (JNICALL *CallStaticLongMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jlong (JNICALL *CallStaticLongMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jlong (JNICALL *CallStaticLongMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jfloat (JNICALL *CallStaticFloatMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jfloat (JNICALL *CallStaticFloatMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jfloat (JNICALL *CallStaticFloatMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
jdouble (JNICALL *CallStaticDoubleMethod)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
jdouble (JNICALL *CallStaticDoubleMethodV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
jdouble (JNICALL *CallStaticDoubleMethodA)
(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
void (JNICALL *CallStaticVoidMethod)
(JNIEnv *env, jclass cls, jmethodID methodID, ...);
void (JNICALL *CallStaticVoidMethodV)
(JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
void (JNICALL *CallStaticVoidMethodA)
(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);
jfieldID (JNICALL *GetStaticFieldID)
(JNIEnv *env, jclass clazz, const char *name, const char *sig);
jobject (JNICALL *GetStaticObjectField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jboolean (JNICALL *GetStaticBooleanField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jbyte (JNICALL *GetStaticByteField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jchar (JNICALL *GetStaticCharField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jshort (JNICALL *GetStaticShortField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jint (JNICALL *GetStaticIntField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jlong (JNICALL *GetStaticLongField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jfloat (JNICALL *GetStaticFloatField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
jdouble (JNICALL *GetStaticDoubleField)
(JNIEnv *env, jclass clazz, jfieldID fieldID);
void (JNICALL *SetStaticObjectField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value);
void (JNICALL *SetStaticBooleanField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value);
void (JNICALL *SetStaticByteField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value);
void (JNICALL *SetStaticCharField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value);
void (JNICALL *SetStaticShortField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value);
void (JNICALL *SetStaticIntField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
void (JNICALL *SetStaticLongField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value);
void (JNICALL *SetStaticFloatField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value);
void (JNICALL *SetStaticDoubleField)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value);
jstring (JNICALL *NewString)
(JNIEnv *env, const jchar *unicode, jsize len);
jsize (JNICALL *GetStringLength)
(JNIEnv *env, jstring str);
const jchar *(JNICALL *GetStringChars)
(JNIEnv *env, jstring str, jboolean *isCopy);
void (JNICALL *ReleaseStringChars)
(JNIEnv *env, jstring str, const jchar *chars);
jstring (JNICALL *NewStringUTF)
(JNIEnv *env, const char *utf);
jsize (JNICALL *GetStringUTFLength)
(JNIEnv *env, jstring str);
const char* (JNICALL *GetStringUTFChars)
(JNIEnv *env, jstring str, jboolean *isCopy);
void (JNICALL *ReleaseStringUTFChars)
(JNIEnv *env, jstring str, const char* chars);
jsize (JNICALL *GetArrayLength)
(JNIEnv *env, jarray array);
jobjectArray (JNICALL *NewObjectArray)
(JNIEnv *env, jsize len, jclass clazz, jobject init);
jobject (JNICALL *GetObjectArrayElement)
(JNIEnv *env, jobjectArray array, jsize index);
void (JNICALL *SetObjectArrayElement)
(JNIEnv *env, jobjectArray array, jsize index, jobject val);
jbooleanArray (JNICALL *NewBooleanArray)
(JNIEnv *env, jsize len);
jbyteArray (JNICALL *NewByteArray)
(JNIEnv *env, jsize len);
jcharArray (JNICALL *NewCharArray)
(JNIEnv *env, jsize len);
jshortArray (JNICALL *NewShortArray)
(JNIEnv *env, jsize len);
jintArray (JNICALL *NewIntArray)
(JNIEnv *env, jsize len);
jlongArray (JNICALL *NewLongArray)
(JNIEnv *env, jsize len);
jfloatArray (JNICALL *NewFloatArray)
(JNIEnv *env, jsize len);
jdoubleArray (JNICALL *NewDoubleArray)
(JNIEnv *env, jsize len);
jboolean * (JNICALL *GetBooleanArrayElements)
(JNIEnv *env, jbooleanArray array, jboolean *isCopy);
jbyte * (JNICALL *GetByteArrayElements)
(JNIEnv *env, jbyteArray array, jboolean *isCopy);
jchar * (JNICALL *GetCharArrayElements)
(JNIEnv *env, jcharArray array, jboolean *isCopy);
jshort * (JNICALL *GetShortArrayElements)
(JNIEnv *env, jshortArray array, jboolean *isCopy);
jint * (JNICALL *GetIntArrayElements)
(JNIEnv *env, jintArray array, jboolean *isCopy);
jlong * (JNICALL *GetLongArrayElements)
(JNIEnv *env, jlongArray array, jboolean *isCopy);
jfloat * (JNICALL *GetFloatArrayElements)
(JNIEnv *env, jfloatArray array, jboolean *isCopy);
jdouble * (JNICALL *GetDoubleArrayElements)
(JNIEnv *env, jdoubleArray array, jboolean *isCopy);
void (JNICALL *ReleaseBooleanArrayElements)
(JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode);
void (JNICALL *ReleaseByteArrayElements)
(JNIEnv *env, jbyteArray array, jbyte *elems, jint mode);
void (JNICALL *ReleaseCharArrayElements)
(JNIEnv *env, jcharArray array, jchar *elems, jint mode);
void (JNICALL *ReleaseShortArrayElements)
(JNIEnv *env, jshortArray array, jshort *elems, jint mode);
void (JNICALL *ReleaseIntArrayElements)
(JNIEnv *env, jintArray array, jint *elems, jint mode);
void (JNICALL *ReleaseLongArrayElements)
(JNIEnv *env, jlongArray array, jlong *elems, jint mode);
void (JNICALL *ReleaseFloatArrayElements)
(JNIEnv *env, jfloatArray array, jfloat *elems, jint mode);
void (JNICALL *ReleaseDoubleArrayElements)
(JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode);
void (JNICALL *GetBooleanArrayRegion)
(JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
void (JNICALL *GetByteArrayRegion)
(JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
void (JNICALL *GetCharArrayRegion)
(JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
void (JNICALL *GetShortArrayRegion)
(JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
void (JNICALL *GetIntArrayRegion)
(JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
void (JNICALL *GetLongArrayRegion)
(JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
void (JNICALL *GetFloatArrayRegion)
(JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
void (JNICALL *GetDoubleArrayRegion)
(JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
void (JNICALL *SetBooleanArrayRegion)
(JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf);
void (JNICALL *SetByteArrayRegion)
(JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf);
void (JNICALL *SetCharArrayRegion)
(JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf);
void (JNICALL *SetShortArrayRegion)
(JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf);
void (JNICALL *SetIntArrayRegion)
(JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf);
void (JNICALL *SetLongArrayRegion)
(JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf);
void (JNICALL *SetFloatArrayRegion)
(JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf);
void (JNICALL *SetDoubleArrayRegion)
(JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf);
jint (JNICALL *RegisterNatives)
(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
jint nMethods);
jint (JNICALL *UnregisterNatives)
(JNIEnv *env, jclass clazz);
jint (JNICALL *MonitorEnter)
(JNIEnv *env, jobject obj);
jint (JNICALL *MonitorExit)
(JNIEnv *env, jobject obj);
jint (JNICALL *GetJavaVM)
(JNIEnv *env, JavaVM **vm);
void (JNICALL *GetStringRegion)
(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
void (JNICALL *GetStringUTFRegion)
(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
void * (JNICALL *GetPrimitiveArrayCritical)
(JNIEnv *env, jarray array, jboolean *isCopy);
void (JNICALL *ReleasePrimitiveArrayCritical)
(JNIEnv *env, jarray array, void *carray, jint mode);
const jchar * (JNICALL *GetStringCritical)
(JNIEnv *env, jstring string, jboolean *isCopy);
void (JNICALL *ReleaseStringCritical)
(JNIEnv *env, jstring string, const jchar *cstring);
jweak (JNICALL *NewWeakGlobalRef)
(JNIEnv *env, jobject obj);
void (JNICALL *DeleteWeakGlobalRef)
(JNIEnv *env, jweak ref);
jboolean (JNICALL *ExceptionCheck)
(JNIEnv *env);
jobject (JNICALL *NewDirectByteBuffer)
(JNIEnv* env, void* address, jlong capacity);
void* (JNICALL *GetDirectBufferAddress)
(JNIEnv* env, jobject buf);
jlong (JNICALL *GetDirectBufferCapacity)
(JNIEnv* env, jobject buf);
/* New JNI 1.6 Features */
jobjectRefType (JNICALL *GetObjectRefType)
(JNIEnv* env, jobject obj);
/* Module Features */
jobject (JNICALL *GetModule)
(JNIEnv* env, jclass clazz);
};
struct JNIEnv_ {
const struct JNINativeInterface_ *functions;
};
/*
* optionString may be any option accepted by the JVM, or one of the
* following:
*
* -D<name>=<value> Set a system property.
* -verbose[:class|gc|jni] Enable verbose output, comma-separated. E.g.
* "-verbose:class" or "-verbose:gc,class"
* Standard names include: gc, class, and jni.
* All nonstandard (VM-specific) names must begin
* with "X".
* vfprintf extraInfo is a pointer to the vfprintf hook.
* exit extraInfo is a pointer to the exit hook.
* abort extraInfo is a pointer to the abort hook.
*/
typedef struct JavaVMOption {
char *optionString;
void *extraInfo;
} JavaVMOption;
typedef struct JavaVMInitArgs {
jint version;
jint nOptions;
JavaVMOption *options;
jboolean ignoreUnrecognized;
} JavaVMInitArgs;
typedef struct JavaVMAttachArgs {
jint version;
char *name;
jobject group;
} JavaVMAttachArgs;
/* These will be VM-specific. */
#define JDK1_2
#define JDK1_4
/* End VM-specific. */
struct JNIInvokeInterface_ {
void *reserved0;
void *reserved1;
void *reserved2;
jint (JNICALL *DestroyJavaVM)(JavaVM *vm);
jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args);
jint (JNICALL *DetachCurrentThread)(JavaVM *vm);
jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);
jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args);
};
struct JavaVM_ {
const struct JNIInvokeInterface_ *functions;
};
#ifdef _JNI_IMPLEMENTATION_
#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT
#else
#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT
#endif
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
JNI_GetDefaultJavaVMInitArgs(void *args);
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
/* Defined by native libraries. */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved);
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved);
#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006
#define JNI_VERSION_1_8 0x00010008
#define JNI_VERSION_9 0x00090000
#define JNI_VERSION_10 0x000a0000
—
Reply to this email directly, view it on GitHub
<#1140 (reply in thread)>,
or unsubscribe
</~https://github.com/notifications/unsubscribe-auth/ABALZX5MCY2TRORUU2NCMTTWST3MVANCNFSM6AAAAAATXWTVR4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Really childish to come to a modula3 list and promote Go :).
I am using Go in a big project where also some Modula-3 is used. Languages are tools, not sport teams. With deeper knowledge comes deeper understanding and there one can find best fit for whatever tools he/she is in command of.
… On 13. 1. 2023., at 16:46, tn1997tn ***@***.***> wrote:
yeah, cgo seems to be more advanced than anything CM3 has. i know about go since it debut but have never used it. i only know it's designed to build web services.
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWHVXUEWCUTB6VN4YUDWSF2GVANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you are subscribed to this thread.
|
Beta Was this translation helpful? Give feedback.
-
I had never done anything with Swig or any binding generator before, but
in thinking about tn1997tn's questions about passing an array of character
strings, I realize that fully automated generation of good idiomatic bindings
from C code is fundamentally impossible, because of C/C++'s very weak type
system, relative to almost any other language.
Pointers are the biggest problem. There is no way of knowing from a C prototype
whether a pointer is to a single item or an element of an array, and if
the latter, what its bounds are in either direction. Independent of that,
you also can't tell if the pointer means it is intended as a result parameter
or not.
In the case of an array, is it terminated by some sentinel element with a
special value like \000 or null/NIL, etc., or is the range communicated by
a separate parameter or some other way. Both are common in C code, and the
type system can not convey this.
Nor do you know if a char is really a character or a limited range integer.
So should it be bound to CHAR, TEXT, an integer subrange, or an array
thereof?
Or, you could just have the M3 signatures take parameters in M3-equivalents
to low-level C types and let the writer of every call hand-code conversions,
using unsafe code. But that is very not nice, and probably would amount
to nothing more than the EXTERNAL declarations, any additional wrapper
amounting to a useless noop.
…On 1/16/23 01:26, peter mckinna wrote:
In the process of updating it. Temporarily it's swigm3 (confusingly) but I followed someone's suggestion to fork
from the original swig in order to track their changes. I will push these updates soon.
But to get the appropriate types for your signature you probably have to override the default
typemaps. In fact usually you have to override a group of them. Learning about typemaps is
a bit hit-and-miss and takes some time to master. (I certainly would not call myself an expert).
But swig certainly helps generate interfaces where there are lots of function defs. It does, however, have
a high barrier for entry.
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNDEULR22LOCP4UPJNTWSTZZBANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
DL.i3:
INTERFACE DL;
EXCEPTION
Error(TEXT);
TYPE
T <: Public;
Public = OBJECT
METHODS
init(filename: TEXT; global: BOOLEAN := FALSE): T RAISES { Error };
close();
sym(name: TEXT): Sym RAISES { Error };
END;
Sym <: PublicSym;
PublicSym = OBJECT
addr: ADDRESS;
METHODS
execute();
END;
END DL.
DL.m3 for WIN32:
UNSAFE MODULE DL;
IMPORT
M3toC;
FROM
Ctypes
IMPORT
char_star,
void_star;
FROM
WinDef
IMPORT
HINSTANCE;
FROM
WinBase
IMPORT
LoadLibraryA,
GetProcAddress;
REVEAL
T = Public BRANDED "HoNet-DL.T-1.0" OBJECT
h: HINSTANCE;
OVERRIDES
init := Init;
close := Close;
sym := GetSym;
END;
Sym = PublicSym BRANDED "HoNet-DL.Sym-1.0" OBJECT
OVERRIDES
execute := Execute;
END;
PROCEDURE Init(t: T; filename: TEXT; global: BOOLEAN := FALSE): T RAISES { Error } =
VAR
name: char_star;
err: TEXT;
BEGIN
IF filename = NIL THEN
filename := "hm3gtk2.dll";
END;
name := M3toC.CopyTtoS(filename);
TRY
t.h := LoadLibraryA(name);
IF t.h = NIL THEN
(*
err := M3toC.CopyStoT(dlerror());
*)
err := "ERROR: Unable to load DLL (" & filename & ")";
RAISE Error(err);
END;
RETURN t;
FINALLY
M3toC.FreeCopiedS(name);
END;
END Init;
PROCEDURE Close(t: T) =
BEGIN
END Close;
PROCEDURE GetSym(t: T; name: TEXT): Sym RAISES { Error } =
VAR
h: HINSTANCE := t.h;
sym: Sym;
symbol: void_star := M3toC.CopyTtoS(name);
BEGIN
TRY
sym := NEW(Sym, addr := LOOPHOLE(GetProcAddress(h, symbol), ADDRESS));
IF sym.addr = NIL THEN
RAISE Error("ERROR: unable to find DLL function (" & name & ")");
END;
RETURN sym;
FINALLY
M3toC.FreeCopiedS(symbol);
END;
END GetSym;
PROCEDURE Execute(sym: Sym) =
BEGIN
IF sym.addr = NIL THEN
RETURN;
END;
LOOPHOLE(sym.addr, PROCEDURE())();
END Execute;
BEGIN
END DL.
… On 16. 1. 2023., at 17:37, tn1997tn ***@***.***> wrote:
Are you sure your code also work on Windows? I'm on Windows with a MinGW based CM3. Windows doesn't have dlopen nor dlsym. The CM3 library covers Linux only with no compatibility layer for Windows like what FreeBasic provides. See: #1140 (reply in thread) <#1140 (reply in thread)>
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWBG3MKOEZGMUMMJDXTWSV2NZANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
Peter mentioned that, I think. When doing bindings, you must create adequate Module-3 type mapping.
I did a lot of binding, always by hand.
… On 16. 1. 2023., at 18:13, Rodney M. Bates ***@***.***> wrote:
I had never done anything with Swig or any binding generator before, but
in thinking about tn1997tn's questions about passing an array of character
strings, I realize that fully automated generation of good idiomatic bindings
from C code is fundamentally impossible, because of C/C++'s very weak type
system, relative to almost any other language.
Pointers are the biggest problem. There is no way of knowing from a C prototype
whether a pointer is to a single item or an element of an array, and if
the latter, what its bounds are in either direction. Independent of that,
you also can't tell if the pointer means it is intended as a result parameter
or not.
In the case of an array, is it terminated by some sentinel element with a
special value like \000 or null/NIL, etc., or is the range communicated by
a separate parameter or some other way. Both are common in C code, and the
type system can not convey this.
Nor do you know if a char is really a character or a limited range integer.
So should it be bound to CHAR, TEXT, an integer subrange, or an array
thereof?
Or, you could just have the M3 signatures take parameters in M3-equivalents
to low-level C types and let the writer of every call hand-code conversions,
using unsafe code. But that is very not nice, and probably would amount
to nothing more than the EXTERNAL declarations, any additional wrapper
amounting to a useless noop.
On 1/16/23 01:26, peter mckinna wrote:
>
> In the process of updating it. Temporarily it's swigm3 (confusingly) but I followed someone's suggestion to fork
> from the original swig in order to track their changes. I will push these updates soon.
> But to get the appropriate types for your signature you probably have to override the default
> typemaps. In fact usually you have to override a group of them. Learning about typemaps is
> a bit hit-and-miss and takes some time to master. (I certainly would not call myself an expert).
> But swig certainly helps generate interfaces where there are lots of function defs. It does, however, have
> a high barrier for entry.
>
> —
> Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNDEULR22LOCP4UPJNTWSTZZBANCNFSM6AAAAAATXWTVR4>.
> You are receiving this because you commented.Message ID: ***@***.***>
>
—
Reply to this email directly, view it on GitHub <#1140 (comment)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWAI6PBGZVENA5VHS7DWSV6SPANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
Oh, really? How would I know that, I was not a coder before 1981? :)
Tell me, do you have some Modula-3 project on? Solving something real-world or some pet project, whatever?
… On 18. 1. 2023., at 09:38, nsgnkhibdk2cls0f ***@***.***> wrote:
Modula-3 is coming with its own runtime. It is not trivial to do what you are asking for. I did it earlier (Modula-3 as a dynamic library), linked final executable as shared library etc… But it is not really what you use Modula-3 for.
To use Modula-3 library in other languages you must initialize its runtime type system, ensure threads are working etc. Not trivial.
You can embed the JVM (jvm.dll) into C/C++ programs easily. Almost any programming languages in the world have their own runtimes!
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWCDUMA72DQQYCAHAZDWS6TZVANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
As one grows up he becomes more skilled and more efficient. That’s how it works :).
One develops own ways, methods, tools even, does some tasks repeatedly and as time passes he finds even better and more optimal ways. Etc :).
… On 18. 1. 2023., at 15:57, nsgnkhibdk2cls0f ***@***.***> wrote:
I did a lot of binding, always by hand.
You indeed have a lot of time!
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWGF45YSKRO4CN7S3LTWTAAHLANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
Yet, it does not have OOP :).
Modula-3 type system and modules with it are unique across the world of programming languages. Most of us here find it important enough to invest our time and resources in it for decades :).
… On 18. 1. 2023., at 09:41, nsgnkhibdk2cls0f ***@***.***> wrote:
What's wrong with it? Btw, I didn't promote Go. I only show Go is superior in almost every aspects. If Go has OOP, it will completely superior!
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWGUWV3YOYHUZH2OB3LWS6UFNANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
I have codebase of 1.5+ million lines of Modula-2 in my private repositories, wrote full framework for my development up to and including a relational database, used in lots of various software I (with few guys working for and with me) wrote and sold in 90s and 00s :).
I certainly am aware of Pascals, Oberons and Modulas and 100% sure you do not have clear idea about any :).
And yes, Modula-3 is what I wrote - unique. While Wirth is a great guy with a knack for programming languages, Luca Cardelli, Bill Kalsow and rest of guys in SRC and other Digital labs are also not too shabby :).
… On 18. 1. 2023., at 17:52, nsgnkhibdk2cls0f ***@***.***> wrote:
Try Oberon+, Modula-3 is not unique: /~https://github.com/rochus-keller/Oberon </~https://github.com/rochus-keller/Oberon>
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWEGZHEBIURYIK2E72TWTANV7ANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
You are right about this, though 😄 |
Beta Was this translation helpful? Give feedback.
-
You should wrote that st start, to save me some time :).
Enjoy your browsing of languages :).
… On 18. 1. 2023., at 20:05, nsgnkhibdk2cls0f ***@***.***> wrote:
I have codebase of 1.5+ million lines of Modula-2 in my private repositories, wrote full framework for my development up to and including a relational database, used in lots of various software I (with few guys working for and with me) wrote and sold in 90s and 00s :).
As I said, you are a professional. I'm an amateur has no background in CS 😄
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWF2LAOI3QTUUTZPW23WTA5GVANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
I do not think Wirth learned lessons from Modula-3. He always had its own way and he did not involve himself in Modula-3. He just gave his best wishes and went his own way :).
Also, his projects were mostly educational in nature and based around other things he researched. Same is true for DEC SRC, it’s only them being more practical so we today have very usable cm3 product. Oberon is also something which evolves with more of his blessing than of his involvement.
We Modula-2'ers went either Modula-3 or Oberon, or Java, C#, these days Go. Some remained with GNU Modula-2 and for some time I was stress testing it with my code. I like to believe I helped Gaius make better product :).
Modula-3 remains alive product although not yet 1st class citizen of the world of free programming languages. We need some more tools around it, among other things.
… On 18. 1. 2023., at 20:03, nsgnkhibdk2cls0f ***@***.***> wrote:
It's created much much later than Modula-3 so it could learned the lessons from Modula-3 and it could incorporate all of the improvements of the Oberon language too. Long story short, it's more recent, has better tooling, has someone dedicated on it (rochus-keller), and the biggest plus is it has it own Qt based IDE, what Modula-3 has never have 😄
—
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/AA5ZBWBPQI2WN5F6UU53QM3WTA5BBANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
-
WeakRef page's format is broken, please have a look: https://modula3.github.io/cm3/help/gen_html/m3core/src/weakref/WeakRef.i3.html |
Beta Was this translation helpful? Give feedback.
-
( I'm again on smartphone... I can write comments, but can't write answers (?) ) "While I remember": We have m2tom3. It's Modula-2 to Modula-3 converter. P.S.
Please, see file m2tom3_v2.03_and_FIXes_Modula-2_to_Modula-3_converter.7z |
Beta Was this translation helpful? Give feedback.
-
Sorry, but this discussion forum is about Modula-3, not Modula-2 |
Beta Was this translation helpful? Give feedback.
-
On 1/18/23 11:14, nsgnkhibdk2cls0f wrote:
Oberon+ has everything M3 has, plus it's more modern. It's my point to counter his point about M3 is unique. M3 is not unique at all 😄
Modula-3 is unique or unusual in a number of ways. The one I consider
most significant is its unmatched economy of concept, meaning a high
ratio of useful language features to size/complexity of the language
definition.
The last edition of C++ I am seriously familiar with (at least two
significant revisions old) is 6x M3, i.e., 300 pages vs. 50. And C++
lacks a lot that M3 provides. E.g., C++ has a very poor type system
that is really not much above assembly language and, aside from the
binding problems and others being discussed here, also makes garbage
collection virtually impossible. A lot of the stuff C++ does have
has zero or negative value for coding, maintenance, etc.
M3 is about 3x+ over the various Oberons, so they represent the low
end of the language complexity spectrum. But they have a lot of omissions
that can be coded-around, but sometimes only awkwardly or unsafely.
But certainly, Wirth is the champion of absolute language simplicity.
Language complexity has very real costs, as you who are struggling
to understand 50-page M3 will appreciate relative to Java, which is
8x M3 (400+ pages), and has less in it than any mentioned here.
I can personally testify from having seen many troubles, that the
old rationalization that a lot of stuff in a language is just
irrelevant and can be ignored by working programmers is false.
Occasionally, some of those arcane details you thought didn't
affect you will trip you up, and when it happens, it can take up
more of your time than thousands of lines of routine coding.
Language complexity also means later, more expensive, and buggier
compilers. And then there are inconsistent or inaccurate
interpretations by compiler writers themselves, yet another
source of trip-ups.
With complexity recognized as a cost, Modula-3 gives more bang
for the buck, by a big margin, than any other language I have seen.
… —
Reply to this email directly, view it on GitHub <#1140 (reply in thread)>, or unsubscribe </~https://github.com/notifications/unsubscribe-auth/ABSVZNCHXTPUTNPMGLGKUM3WTAQJDANCNFSM6AAAAAATXWTVR4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
All reactions