1. wrapping C code - my exercise in incompetence.

Hello benevolent Eu masters. As mentioned previously, I am working on wrapping the ASSIMP library. Things are going moderately, kinda, OK but I am having some issues with either total incompetence or some deeper and more sinister, intellectual defect. What I present here, is my humble efforts at peeking and poking my way through the mother of all C structures. So much peeking and poking in fact that I somewhat suspect it could be considered sexual harrassment in some states.

Anyways, I have the following C Structures which I am trying to get all the data out of and place in Eu sequences. Some of it works perfectly and some doesn't work at all as noted.

C:

struct aiScene 
{ 
 
        /** Any combination of the AI_SCENE_FLAGS_XXX flags. By default  
        * this value is 0, no flags are set. Most applications will 
        * want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE  
        * bit set. 
        */ 
        unsigned int mFlags; 
 
 
        /** The root node of the hierarchy.  
        *  
        * There will always be at least the root node if the import 
        * was successful (and no special flags have been set).  
        * Presence of further nodes depends on the format and content  
        * of the imported file. 
        */ 
        C_STRUCT aiNode* mRootNode; 
 
 
 
        /** The number of meshes in the scene. */ 
        unsigned int mNumMeshes; 
 
        /** The array of meshes.  
        * 
        * Use the indices given in the aiNode structure to access  
        * this array. The array is mNumMeshes in size. If the 
        * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always  
        * be at least ONE material. 
        */ 
        C_STRUCT aiMesh** mMeshes; 
 
 
 
        /** The number of materials in the scene. */ 
        unsigned int mNumMaterials; 
 
        /** The array of materials.  
        *  
        * Use the index given in each aiMesh structure to access this 
        * array. The array is mNumMaterials in size. If the 
        * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always  
        * be at least ONE material. 
        */ 
        C_STRUCT aiMaterial** mMaterials; 
 
 
 
        /** The number of animations in the scene. */ 
        unsigned int mNumAnimations;  
 
        /** The array of animations.  
        * 
        * All animations imported from the given file are listed here. 
        * The array is mNumAnimations in size. 
        */ 
        C_STRUCT aiAnimation** mAnimations; 
 
 
 
        /** The number of textures embedded into the file */ 
        unsigned int mNumTextures; 
 
        /** The array of embedded textures. 
        *  
        * Not many file formats embed their textures into the file. 
        * An example is Quake's MDL format (which is also used by 
        * some GameStudio versions) 
        */ 
        C_STRUCT aiTexture** mTextures; 
 
 
        /** The number of light sources in the scene. Light sources 
        * are fully optional, in most cases this attribute will be 0  
        */ 
        unsigned int mNumLights; 
 
        /** The array of light sources. 
        *  
        * All light sources imported from the given file are 
        * listed here. The array is mNumLights in size. 
        */ 
        C_STRUCT aiLight** mLights; 
 
 
        /** The number of cameras in the scene. Cameras 
        * are fully optional, in most cases this attribute will be 0  
        */ 
        unsigned int mNumCameras; 
 
        /** The array of cameras. 
        *  
        * All cameras imported from the given file are listed here. 
        * The array is mNumCameras in size. The first camera in the 
        * array (if existing) is the default camera view into 
        * the scene. 
        */ 
        C_STRUCT aiCamera** mCameras; 
} 
 
aiMaterial 
    /** List of all material properties loaded. */ 
    C_STRUCT aiMaterialProperty** mProperties; 
 
    /** Number of properties in the data base */ 
    unsigned int mNumProperties; 
 
         /** Storage allocated */ 
    unsigned int mNumAllocated; 
 
 
aiMaterialProperty 
struct aiMaterialProperty 
{ 
    /** Specifies the name of the property (key) 
     *  Keys are generally case insensitive.  
     */ 
    C_STRUCT aiString mKey; 
 
        /** Textures: Specifies their exact usage semantic. 
         * For non-texture properties, this member is always 0  
         * (or, better-said, #aiTextureType_NONE). 
         */ 
        unsigned int mSemantic; 
 
        /** Textures: Specifies the index of the texture. 
         *  For non-texture properties, this member is always 0. 
         */ 
        unsigned int mIndex; 
 
    /** Size of the buffer mData is pointing to, in bytes. 
         *  This value may not be 0. 
     */ 
    unsigned int mDataLength; 
 
    /** Type information for the property. 
     * 
     * Defines the data layout inside the data buffer. This is used 
         * by the library internally to perform debug checks and to  
         * utilize proper type conversions.  
         * (It's probably a hacky solution, but it works.) 
     */ 
    C_ENUM aiPropertyTypeInfo mType; 
 
    /** Binary buffer to hold the property's value. 
     * The size of the buffer is always mDataLength. 
     */ 
    char* mData; 

new topic     » topic index » view message » categorize

2. Re: wrapping C code - my exercise in incompetence.

Eucode:

function get_mat_properties(atom ptr, integer numProps) 
 
	sequence props, tprop, blob 
	atom tptr, loc 
	 
	props = {} 
	loc = peek4u(ptr) 
 
	--blob = peek({loc, 2000})	testing 
	--writedebugai("blob.txt", blob) 
	 
	for impm = 0 to numProps-1 do 
		tprop = AI_MATERIAL_PROPERTY 
		 
		tprop[1] = get_aiString_sequence(loc)	-- *** works perfectly		 
                 loc += length(tprop[1][2]) + 5 
		tprop[2] = peek4u(loc)			-- incorrect value			--UINT  
		loc += 4 
		tprop[3] = peek4u(loc)		-- incorrect value				--UINT  
		loc += 4		 
		tprop[4] = peek4u(loc)	   -- incorrect value				--UINT 
		loc += 4		 
		tprop[5] = peek4u(loc)	-- incorrect value					--UINT 
		loc += 4		 
		tprop[6] = {peek4u(loc)}  -- char * mData  -- incorrect value		loc += 4                  -- I know this is wrong its just returning the pointer to test. 
		 
		props &= {tprop} 
	end for 
	 
	return props 
 
end function 
 
function get_materials(atom ptr, integer numMats)  -- ***this function works perfectly. 
 
	sequence mats, tmat 
	atom propsloc, tptr 
	 
	mats = {} 
	 
	for impx = 0 to numMats-1 do 
	 
		tmat = AI_MATERIAL		--  a sequence structure  
		tptr = peek4u(ptr + (impx*4))		-- ptr  
		 
		propsloc = peek4u(tptr) 
		tmat[2] = peek4u(tptr+4) 
		tmat[3] = peek4u(tptr+8)	 
		tmat[1] = get_mat_properties(propsloc, tmat[2]) 
		 
		mats &= {tmat} 
	end for	 
 
	return mats 
end function 
 
public function euConvertScene(atom aiScene)		-- aiScene is a ptr to the scene object 
 
	sequence euScene, mesh, norms, uvs 
	atom node_ptr, mesh_ptr, mats_ptr, anims_ptr, txtr_ptr, lights_ptr, cam_ptr 
		 
	euScene = AI_SCENE 
	mesh = {} 
	norms = {} 
	uvs = {} 
	 
	node_ptr = peek4u(aiScene + 4) 
	mesh_ptr = peek4u(aiScene + 12) 
	mats_ptr = peek4u(aiScene + 20) 
	anims_ptr = peek4u(aiScene + 28) 
	txtr_ptr = peek4u(aiScene + 36) 
	lights_ptr = peek4u(aiScene + 44) 
	cam_ptr = peek4u(aiScene + 52) 
	 
	euScene[1] = peek4u(aiScene)					-- get flags	 
	euScene[2] = get_node_sequence(node_ptr) 
	euScene[3] = peek4u(aiScene+8) 				-- numMeshes 
	euScene[4] = get_meshes(mesh_ptr, euScene[3])	-- get all meshes 
	euScene[5] = peek4u(aiScene+16)				-- numMaterials 
	euScene[6] = get_materials(mats_ptr, euScene[5])  
	euScene[7] = peek4u(aiScene+24)				-- anims 
	euScene[8] = {anims_ptr} 
	euScene[9] = peek4u(aiScene+32) 				-- textures 
	euScene[10] = {txtr_ptr}	 
	euScene[11] = peek4u(aiScene+40)				--lights 
	euScene[12] = {lights_ptr} 
	euScene[13] = peek4u(aiScene+48)				-- cams 
	euScene[14] = {cam_ptr}	 
	 
	writedebugai("assimp_check.txt", euScene) 
 
	return euScene 
 
end function 
 
new topic     » goto parent     » topic index » view message » categorize

3. Re: wrapping C code - my exercise in incompetence.

So my question is... where am I going wrong in my get_mat_properties() routine? Am I pointing in the wrong place? If so, why does my get_aiString_sequence() consistently give me the correct value? Ugh, this is the better part of the memory blob, the mesh chunk is even worse. :)

Thanks,

Steve A.

new topic     » goto parent     » topic index » view message » categorize

4. Re: wrapping C code - my exercise in incompetence.

ssallen said...

So my question is... where am I going wrong in my get_mat_properties() routine? Am I pointing in the wrong place? If so, why does my get_aiString_sequence() consistently give me the correct value? Ugh, this is the better part of the memory blob, the mesh chunk is even worse.

Can we see your code for get_aiString_sequence()?

-Greg

new topic     » goto parent     » topic index » view message » categorize

5. Re: wrapping C code - my exercise in incompetence.

Yep, I will post it tomorrow. Its on my work computer unfortunately.

new topic     » goto parent     » topic index » view message » categorize

6. Re: wrapping C code - my exercise in incompetence.

Looking at aiString declaration here: http://realxtend-naali-deps.googlecode.com/svn-history/r64/bin/build_deps/assimp/include/aiTypes.h
I think the problem is that aiString's sizeof is not 5. It may be something like 1024 (MAXLEN) + size_t (which I assume is 4). Just guessing by taking a quick look at that declaration, I may be wrong and probably your get_aistring_sequence will shed some light to this.

Edit: I knew Eu4 had size_t defined, the size may vary: http://openeuphoria.org/docs/std_dll.html#_5402_c_size_t

new topic     » goto parent     » topic index » view message » categorize

7. Re: wrapping C code - my exercise in incompetence.

gbonvehi said...

Looking at aiString declaration here: http://realxtend-naali-deps.googlecode.com/svn-history/r64/bin/build_deps/assimp/include/aiTypes.h
I think the problem is that aiString's sizeof is not 5. It may be something like 1024 (MAXLEN) + size_t (which I assume is 4). Just guessing by taking a quick look at that declaration, I may be wrong and probably your get_aistring_sequence will shed some light to this.

That's exactly what I was thinking. We can (for the time being) assume size_t is an unsigned int (4 bytes). So the aiString structure should be 1028 bytes.

Side note #1: Once Euphoria goes 64-bit, some logic will be required to determine the platform and set size_t to long unsigned int (8 bytes) instead.

Side note #2: This is a poor method to use. They really should have used a pointer to the aiString structure instead of embedding it directly; this really bloats the structure.

gbonvehi said...

Edit: I knew Eu4 had size_t defined, the size may vary: http://openeuphoria.org/docs/std_dll.html#_5402_c_size_t

Those are constants for define_c_func/proc and are not meant to be sizes in and of themselves. You can, however, shift them down to their respected sizes quite easily:

public function sizeof( atom x ) 
    -- returns 1, 2, 4, or 8 
    return and_bits( x, #FF ) 
end function 
 
public constant SIGNED = 1, UNSIGNED = 2, FLOAT = 3 
 
public function sign( atom x ) 
    -- returns SIGNED, UNSIGNED, or FLOAT 
    return and_bits( x / #1000000, #FF ) 
end function 

Although it's not perfect, since C_DWORDLONG (which is an 8 byte unsigned int) has the same value as C_DOUBLE (which is an 8-byte float). getlost

Edit: this will not be necessary on Euphoria 4.1, since it includes its own sizeof() function and native structure support. smile

-Greg

new topic     » goto parent     » topic index » view message » categorize

8. Re: wrapping C code - my exercise in incompetence.

ghaberek said...

Those are constants for define_c_func/proc and are not meant to be sizes in and of themselves. You can, however, shift them down to their respected sizes quite easily:

Ouch, that's what I get for peeking to quick at the docs, yeap, all C_ are constants used to define things, thanks for the heads up.

ghaberek said...

Edit: this will not be necessary on Euphoria 4.1, since it includes its own sizeof() function and native structure support.

Having sizeof function will help a lot, thanks guys for making interfacing with C easier!

new topic     » goto parent     » topic index » view message » categorize

9. Re: wrapping C code - my exercise in incompetence.

Hello again, here is my get_aiString_Sequence method.

function get_aiString_sequence(atom loc) 
 
	sequence aiStr 
 
	aiStr = AI_STRING 
	aiStr[1] = peek4u(loc)         -- t_size 
	if aiStr[1] < 1 then 
		aiStr[2] = "bad length" 
	else 
		aiStr[2] = peek_string(loc+4)	-- string 
	end if 
	 
	if length(aiStr[2]) != aiStr[1] then 
		-- Handle:  length doesn't match! 
	end if 
	 
	return aiStr 
 
end function 
 
new topic     » goto parent     » topic index » view message » categorize

10. Re: wrapping C code - my exercise in incompetence.

The get_aiString_sequence function seems fine.

According to the structure declaration that I linked above, the size of aiString structure is fixed, so you should change the line

loc += length(tprop[1][2]) + 5 

to

loc += 1024 + 4 -- MAXLEN + size_t 

MAXLEN is defined as 1024 in the .h file and size_t may vary and you can get it dynamically as explained by Greg above but it's probably 4 in your system.

new topic     » goto parent     » topic index » view message » categorize

11. Re: wrapping C code - my exercise in incompetence.

gbonvehi said...

The get_aiString_sequence function seems fine.

According to the structure declaration that I linked above, the size of aiString structure is fixed, so you should change the line

loc += length(tprop[1][2]) + 5 

to

loc += 1024 + 4 -- MAXLEN + size_t 

MAXLEN is defined as 1024 in the .h file and size_t may vary and you can get it dynamically as explained by Greg above but it's probably 4 in your system.

Oh, that makes sense. I just assumed since the first item in the structure was size that it would be the length of the buffer. I'll give this a run and report back. Thanks everyone!

Steve A.

new topic     » goto parent     » topic index » view message » categorize

12. Re: wrapping C code - my exercise in incompetence.

Ok, that fixed a lot of my problems. Thanks everyone!

My new issue is how to deal with this:

ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream( 
        C_ENUM aiDefaultLogStream pStreams, 
        const char* file); 

That function appears to return an actual structure and not a pointer to one. How do I deal with that? Do I have to duplicate the structure in memory by allocating and peeking/poking? The aiLogStream structure looks like this:

struct aiLogStream 
{ 
        /** callback to be called */ 
        aiLogStreamCallback callback; 
 
        /** user data to be passed to the callback */ 
        char* user; 
}; 

and then, of course, the aiLogStreamCallback:

typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);   

new topic     » goto parent     » topic index » view message » categorize

13. Re: wrapping C code - my exercise in incompetence.

ssallen said...

My new issue is how to deal with this:

ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream( 
        C_ENUM aiDefaultLogStream pStreams, 
        const char* file); 

That function appears to return an actual structure and not a pointer to one. How do I deal with that? Do I have to duplicate the structure in memory by allocating and peeking/poking?

It's passing the structure by value instead of by reference, which is another big no-no in many books. Unfortunately, Euphoria is completely incapable of dealing with this correctly. I have dealt with this first-hand, see: define_c_func/proc and 64-bit return types.

I had to resort to writing a "shim" library (dll/so) in C to push the structure from the stack (pass-by-value) to the heap (pass-by-reference, a.k.a. pointers) and back again. I'm afraid you may have to do the same. I'd be glad to help, if you need. You may also be able to use Assembly code to do this, but I've had no such luck. I'm still quite rusty when it comes to Assembly.

ssallen said...

and then, of course, the aiLogStreamCallback:

typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);   

That is not a real function. It is a typedef, which defines how your function should look when passing its reference to other functions. You just need to setup a call_back() and pass that value to whatever function(s) call for it.

public function aiLogStreamCallback( atom pMessage /* char* */, atom pUser /* char* */ ) 
     
    sequence message = peek_string( pMessage ) 
    sequence user = peek_string( pUser ) 
 
    -- do what you need here 
 
    return 0 
end function 
constant alLogStreamCallback_cb = call_back( routine_id("aiLogStreamCallback") ) 

-Greg

new topic     » goto parent     » topic index » view message » categorize

14. Re: wrapping C code - my exercise in incompetence.

Thanks Greg. I will probably take you up on that once I get the rest of the model extracted. I made good progress getting the texture and mesh data out. Now I am just working on the animations.

Incidentally, if the c code has a double, should I use float64_to_atom? Or do I need to use some witchcraft?

        /** Duration of the animation in ticks.  */ 
        double mDuration; 
 
        /** Ticks per second. 0 if not specified in the imported file */ 
        double mTicksPerSecond; 

Disregard, I found the answer.

Thanks!

Steve A.

new topic     » goto parent     » topic index » view message » categorize

15. Re: wrapping C code - my exercise in incompetence.

ghaberek said...

Although it's not perfect, since C_DWORDLONG (which is an 8 byte unsigned int) has the same value as C_DOUBLE (which is an 8-byte float). getlost

In Euphoria 4.1, both have different values. Can't this be changed in 4.05 ?

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

16. Re: wrapping C code - my exercise in incompetence.

jmduro said...
ghaberek said...

Although it's not perfect, since C_DWORDLONG (which is an 8 byte unsigned int) has the same value as C_DOUBLE (which is an 8-byte float). getlost

In Euphoria 4.1, both have different values. Can't this be changed in 4.05 ?

You left out the part of my comment, which I believe is the answer you're seeking.

ghaberek said...

Edit: this will not be necessary on Euphoria 4.1, since it includes its own sizeof() function and native structure support. smile

You can wrap my custom sizeof() stuff in an ifdef EU4_0 block if you want to support both versions.

-Greg

new topic     » goto parent     » topic index » view message » categorize

17. Re: wrapping C code - my exercise in incompetence.

ghaberek said...

You left out the part of my comment, which I believe is the answer you're seeking.

I'm afraid it does not. I try to adapt functions I used in my Low-level Windows wrapper to automatically fill or parse structures according to the computers processor and the compiler release. When I use Eu4.05, I get the same value for both C_DOUBLE and C_DWORDLONG, even with your functions. In one case, I have to deal with a float, in another with a 64-bit integer.

I'm wondering if Eu4.05 knows #03000002 or not (C_DWORDLONG). Maybe I should not care as I use the decimal values.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

18. Re: wrapping C code - my exercise in incompetence.

jmduro said...
ghaberek said...

You left out the part of my comment, which I believe is the answer you're seeking.

I'm afraid it does not. I try to adapt functions I used in my Low-level Windows wrapper to automatically fill or parse structures according to the computers processor and the compiler release. When I use Eu4.05, I get the same value for both C_DOUBLE and C_DWORDLONG, even with your functions. In one case, I have to deal with a float, in another with a 64-bit integer.

I'm wondering if Eu4.05 knows #03000002 or not (C_DWORDLONG). Maybe I should not care as I use the decimal values.

Jean-Marc

4.0.5 (and 4.0.6, when it's released) do not recongize #03000002. The ability for the interpreter to use this value was added in 4.1.0 only.

Here's the section in 4.1.0 that uses this value: http://scm.openeuphoria.org/hg/euphoria/file/16462e686646/source/be_callc.c#l1364

There's the same section in 4.0.6 (or the closest area anyways, the section itself doesn't exist in this version of the file): http://scm.openeuphoria.org/hg/euphoria/file/cbee492464f0/source/be_callc.c#l178

new topic     » goto parent     » topic index » view message » categorize

19. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...

4.0.5 (and 4.0.6, when it's released) do not recongize #03000002. The ability for the interpreter to use this value was added in 4.1.0 only.

Thank you Jim,

I will try to exploit following tables for what I intend to do:

Euphoria 3.1 Euphoria 4.05 Euphoria 4.1
#01000001 C_CHAR C_BYTE, C_CHAR C_BYTE, C_CHAR
#01000002 C_SHORT C_SHORT, C_WORD C_SHORT, C_WORD
#01000004 C_INT, C_LONG C_INT, C_BOOL, C_LONG, C_HRESULT, C_LPARAM, C_WPARAM C_INT, C_BOOL
#01000008 C_LONG, C_HRESULT
#02000001 C_UCHAR C_UBYTE, C_UCHAR C_UBYTE, C_UCHAR
#02000002 C_USHORT C_USHORT C_USHORT
#02000004 C_UINT, C_ULONG, C_POINTER C_UINT, C_DWORD, C_HANDLE, C_HWND, C_POINTER, C_SIZE_T, C_ULONG C_UINT, C_DWORD
#02000008 C_ULONG, C_SIZE_T
#03000001 C_POINTER, C_HANDLE, C_HWND, C_LPARAM, C_WPARAM
#03000002 C_DWORDLONG, C_LONGLONG
#03000004 C_FLOAT C_FLOAT C_FLOAT
#03000008 C_DOUBLE C_DOUBLE, C_DWORDLONG C_DOUBLE
Euphoria 3.1 Euphoria 4.05 Euphoria 4.1
C_BYTE #01000001 #01000001
C_CHAR #01000001 #01000001 #01000001
C_SHORT #01000002 #01000002 #01000002
C_WORD #01000002 #01000002
C_INT #01000004 #01000004 #01000004
C_BOOL #01000004 #01000004
C_LONG #01000004 #01000004 #01000008
C_HRESULT #01000004 #01000008
C_UBYTE #02000001 #02000001
C_UCHAR #02000001 #02000001 #02000001
C_USHORT #02000002 #02000002 #02000002
C_UINT #02000004 #02000004 #02000004
C_DWORD #02000004 #02000004
C_ULONG #02000004 #02000004 #02000008
C_SIZE_T #02000004 #02000008
C_POINTER #02000004 #02000004 #03000001
C_HANDLE #02000004 #03000001
C_HWND #02000004 #03000001
C_LPARAM #01000004 #03000001
C_WPARAM #01000004 #03000001
C_DWORDLONG #03000008 #03000002
C_LONGLONG #03000002
C_FLOAT #03000004 #03000004
C_DOUBLE #03000008 #03000008

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

20. Re: wrapping C code - my exercise in incompetence.

I uploaded a library to allocate, write, read and free structures in memory. Pointers and variables are automatically sized according to OEU version and OS Architecture.

Here is an example of use, no matter if your system is 32-bit or 64-bit, no matter if you use OEU 4.05 or OEU 4.1.

atom p = NULL 
atom s1 = allocate_string("A string") 
p = allocateStructure(p, {C_POINTER, C_INT, C_FLOAT} ) 
writeStructure(p, {C_POINTER, C_INT, C_INT}, {s1, 12, 25.2} ) 
sequence s2 = readStructure(p, {C_POINTER, C_INT, C_INT} ) 
printf(1, "s2[1] = %s, s2[2] = %d, s2[3] = %4.1f\n", {peek_string(s2[1]), s2[2], s2[3]}) 
freeStructure(p, {C_POINTER, C_INT, C_INT} ) 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

21. Re: wrapping C code - my exercise in incompetence.

jmduro said...

I uploaded a library to allocate, write, read and free structures in memory. Pointers and variables are automatically sized according to OEU version and OS Architecture.

Here is an example of use, no matter if your system is 32-bit or 64-bit, no matter if you use OEU 4.05 or OEU 4.1.

atom p = NULL 
atom s1 = allocate_string("A string") 
p = allocateStructure(p, {C_POINTER, C_INT, C_FLOAT} ) 
writeStructure(p, {C_POINTER, C_INT, C_INT}, {s1, 12, 25.2} ) 
sequence s2 = readStructure(p, {C_POINTER, C_INT, C_INT} ) 
printf(1, "s2[1] = %s, s2[2] = %d, s2[3] = %4.1f\n", {peek_string(s2[1]), s2[2], s2[3]}) 
freeStructure(p, {C_POINTER, C_INT, C_INT} ) 

Jean-Marc

test_structures.ex crashed on my system:

 
Ubuntu 15.10, 64-bit 
 
Euphoria Interpreter v4.1.0 development 
   64-bit Linux, Using System Memory 
   Revision Date: 2015-02-02 14:18:53, Id: 5861:57179171dbed 
 
kenneth@kenneth-desktop:~/euprogs/Structures$ ls 
eu_types.ods  ex.err  functions.e  structures.e  test_structures.ex 
kenneth@kenneth-desktop:~/euprogs/Structures$ eui test_structures.ex 
 
/home/kenneth/euprogs/Structures/structures.e:22 in function allocateStructure()  
A machine-level exception occurred during execution of this statement (signal 11)  
 
... called from /home/kenneth/euprogs/Structures/test_structures.ex:10  
 
--> See ex.err 
ex.err: 
/home/kenneth/euprogs/Structures/structures.e:22 in function allocateStructure()  
A machine-level exception occurred during execution of this statement (signal 11)  
    p = 0 
    def = {50331649,16777220,50331652} 
    lg = 0 
    i = 1 
 
... called from /home/kenneth/euprogs/Structures/test_structures.ex:10  
 
 
Public & Export & Global & Local Variables 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/memconst.e: 
    DEP_really_works = 0 
    use_DEP = 1 
    FREE_RID = 2 
    kernel_dll = <no value> 
    memDLL_id = <no value> 
    VirtualAlloc_rid = <no value> 
    VirtualLock_rid = <no value> 
    VirtualUnlock_rid = <no value> 
    VirtualProtect_rid = <no value> 
    GetLastError_rid = <no value> 
    GetSystemInfo_rid = <no value> 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/memory.e: 
    edges_only = <no value> 
    check_calls = 1 
    VirtualFree_rid = <no value> 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/types.e: 
    Defined_Sets = { 
                     {98'b',99'c',100'd',102'f',103'g',104'h',106'j',107'k', 
108'l',109'm',110'n',112'p',113'q',114'r',115's',116't',118'v',119'w',120'x', 
121'y',122'z',66'B',67'C',68'D',70'F',71'G',72'H',74'J',75'K',76'L',77'M', 
78'N',80'P',81'Q',82'R',83'S',84'T',86'V',87'W',88'X',89'Y',90'Z'}, 
                     {97'a',101'e',105'i',111'o',117'u',65'A',69'E',73'I', 
79'O',85'U'}, 
                     { 
                       {48'0',57'9'}, 
                       {65'A',70'F'}, 
                       {97'a',102'f'} 
                     }, 
                     {32' ',9,10,13,11,160}, 
                     { 
                       {32' ',47'/'}, 
                       {58':',63'?'}, 
                       {91'[',96'`'}, 
                       {123'{',126'~'} 
                     }, 
                     { 
                       {32' ',126'~'} 
                     }, 
                     { 
                       {32' ',126'~'}, 
                       {32' ',32' '}, 
                       {9,9}, 
                       {10,10}, 
                       {13,13}, 
                       {8,8}, 
                       {7,7} 
                     }, 
                     { 
                       {97'a',122'z'} 
                     }, 
                     { 
                       {65'A',90'Z'} 
                     }, 
                     { 
                       {48'0',57'9'}, 
                       {97'a',122'z'}, 
                       {65'A',90'Z'} 
                     }, 
                     { 
                       {48'0',57'9'}, 
                       {97'a',122'z'}, 
                       {65'A',90'Z'}, 
                       {95'_',95'_'} 
                     }, 
                     { 
                       {97'a',122'z'}, 
                       {65'A',90'Z'} 
                     }, 
                     { 
                       {0,127} 
                     }, 
                     { 
                       {0,31}, 
                       {127,127} 
                     }, 
                     { 
                       {48'0',57'9'} 
                     }, 
                     { 
                       {33'!',126'~'} 
                     }, 
                     { 
                       {0,255} 
                     }, 
                     {95'_'}, 
                     {1,0} 
                   } 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/machine.e: 
    FREE_ARRAY_RID = 1 
    page_size = 4096 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/convert.e: 
    mem = 18919424 
    decimal_mark = 46'.' 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/datetime.e: 
    yydiff = 80'P' 
    month_names = { 
                    {74'J',97'a',110'n',117'u',97'a',114'r',121'y'}, 
                    {70'F',101'e',98'b',114'r',117'u',97'a',114'r',121'y'}, 
                    {77'M',97'a',114'r',99'c',104'h'}, 
                    {65'A',112'p',114'r',105'i',108'l'}, 
                    {77'M',97'a',121'y'}, 
                    {74'J',117'u',110'n',101'e'}, 
                    {74'J',117'u',108'l',121'y'}, 
                    {65'A',117'u',103'g',117'u',115's',116't'}, 
                    {83'S',101'e',112'p',116't',101'e',109'm',98'b',101'e', 
114'r'}, 
                    {79'O',99'c',116't',111'o',98'b',101'e',114'r'}, 
                    {78'N',111'o',118'v',101'e',109'm',98'b',101'e',114'r'}, 
                    {68'D',101'e',99'c',101'e',109'm',98'b',101'e',114'r'} 
                  } 
    month_abbrs = { 
                    {74'J',97'a',110'n'}, 
                    {70'F',101'e',98'b'}, 
                    {77'M',97'a',114'r'}, 
                    {65'A',112'p',114'r'}, 
                    {77'M',97'a',121'y'}, 
                    {74'J',117'u',110'n'}, 
                    {74'J',117'u',108'l'}, 
                    {65'A',117'u',103'g'}, 
                    {83'S',101'e',112'p'}, 
                    {79'O',99'c',116't'}, 
                    {78'N',111'o',118'v'}, 
                    {68'D',101'e',99'c'} 
                  } 
    day_names = { 
                  {83'S',117'u',110'n',100'd',97'a',121'y'}, 
                  {77'M',111'o',110'n',100'd',97'a',121'y'}, 
                  {84'T',117'u',101'e',115's',100'd',97'a',121'y'}, 
                  {87'W',101'e',100'd',110'n',101'e',115's',100'd',97'a', 
121'y'}, 
                  {84'T',104'h',117'u',114'r',115's',100'd',97'a',121'y'}, 
                  {70'F',114'r',105'i',100'd',97'a',121'y'}, 
                  {83'S',97'a',116't',117'u',114'r',100'd',97'a',121'y'} 
                } 
    day_abbrs = { 
                  {83'S',117'u',110'n'}, 
                  {77'M',111'o',110'n'}, 
                  {84'T',117'u',101'e'}, 
                  {87'W',101'e',100'd'}, 
                  {84'T',104'h',117'u'}, 
                  {70'F',114'r',105'i'}, 
                  {83'S',97'a',116't'} 
                } 
    ampm = { 
             {65'A',77'M'}, 
             {80'P',77'M'} 
           } 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/filesys.e: 
    STAT_VER = 0 
    my_dir = -2 
    InitCurDir = {47'/',104'h',111'o',109'm',101'e',47'/',107'k',101'e',110'n', 
110'n',101'e',116't',104'h',47'/',101'e',117'u',112'p',114'r',111'o',103'g', 
115's',47'/',83'S',116't',114'r',117'u',99'c',116't',117'u',114'r',101'e', 
115's',47'/'} 
    file_counters = {} 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/pretty.e: 
    pretty_end_col = <no value> 
    pretty_chars = <no value> 
    pretty_start_col = <no value> 
    pretty_level = <no value> 
    pretty_file = <no value> 
    pretty_ascii = <no value> 
    pretty_indent = <no value> 
    pretty_ascii_min = <no value> 
    pretty_ascii_max = <no value> 
    pretty_line_count = <no value> 
    pretty_line_max = <no value> 
    pretty_dots = <no value> 
    pretty_line_breaks = <no value> 
    pretty_printing = <no value> 
    pretty_fp_format = <no value> 
    pretty_int_format = <no value> 
    pretty_line = <no value> 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/serialize.e: 
    mem0 = 15736832 
    mem1 = 15736833 
    mem2 = 15736834 
    mem3 = 15736835 
    mem4 = 15736836 
    mem5 = 15736837 
    mem6 = 15736838 
    mem7 = 15736839 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/text.e: 
    lower_case_SET = {} 
    upper_case_SET = {} 
    encoding_NAME = {65'A',83'S',67'C',73'I',73'I'} 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/io.e: 
    mem0 = 17715200 
    mem1 = 17715201 
    mem2 = 17715202 
    mem3 = 17715203 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/scinot.e: 
    NATIVE_FORMAT = 3 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/get.e: 
    input_file = <no value> 
    input_string = <no value> 
    string_next = <no value> 
    ch = <no value> 
    leading_whitespace = <no value> 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/eumem.e: 
    ram_space = {} 
    ram_free_list = 0 
    free_rid = 6 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/primes.e: 
    list_of_primes = {2,3} 
 
 /home/kenneth/euphoria-4.1.0-Linux-x64/include/std/graphcst.e: 
    true_fgcolor = {0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15,16,20,18,22,17, 
21,19,23,24,28,26,28,25,29,17,31} 
    true_bgcolor = {0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15,16,20,18,22,17, 
21,19,23,24,28,26,28,25,29,17,31} 
 
 /home/kenneth/euprogs/Structures/test_structures.ex: 
    p = 0 
    s1 = 15777792 
    s2 = <no value> 
 

new topic     » goto parent     » topic index » view message » categorize

22. Re: wrapping C code - my exercise in incompetence.

Thank you Kenneth,

It took some time but I finally found where it hurts. OE 4.1 does not manage correctly ifdef statements on Linux (Revision Date: 2013-04-15 or Revision Date: 2015-02-02).

If you remove ifdefs and keep only the case statements which apply to your OE version and OS architecture, it will work. Of course there is less value for the library this way.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

23. Re: wrapping C code - my exercise in incompetence.

jmduro said...

It took some time but I finally found where it hurts. OE 4.1 does not manage correctly ifdef statements on Linux (Revision Date: 2013-04-15 or Revision Date: 2015-02-02).

Hmm. Can you give the output of running 'make test' so we can see which (if any) of the ifdef tests are failing?

A short and simple example that demonstrates the bug would help too.

new topic     » goto parent     » topic index » view message » categorize

24. Re: wrapping C code - my exercise in incompetence.

Here it is

t_ifdef.e 
============================================================================ 
all tests successful 
  Passed: ifdef normal (0) 
  Passed: ifdef not (0) 
  Passed: ifdef and (0) 
  Passed: ifdef or 1 (0) 
  Passed: ifdef or 2 (0) 
  Passed: ifdef or 3 (0) 
  Passed: ifdef and not 1 (0) 
  Passed: ifdef and not 2 (0) 
  Passed: ifdef or not 1 (0) 
  Passed: ifdef or not 2 (0) 
  Passed: ifdef and and not (0) 
  Passed: ifdef nested 1 (0) 
  Passed: ifdef nested 2 (0) 
  Passed: found elseifdef ABC or FOO (0) 
  Passed: found 2nd elsifdef, second ifdef DEF (0) 
  Passed: sizeof C_POINTER X86_64 (0) 
  Passed: sizeof C_POINTER BITS64 (0) 
  Passed: sizeof C_LONG LONG64 (0) 
---------------------------------------------------------------------------- 
  (Tests: 0018) (Status:  ok) (Failed: 0000) (Passed: 0018) (Time: 0.000000) 
 
t_ifdef-bound 
============================================================================ 
all tests successful 
  Passed: ifdef normal (0) 
  Passed: ifdef not (0) 
  Passed: ifdef and (0) 
  Passed: ifdef or 1 (0) 
  Passed: ifdef or 2 (0) 
  Passed: ifdef or 3 (0) 
  Passed: ifdef and not 1 (0) 
  Passed: ifdef and not 2 (0) 
  Passed: ifdef or not 1 (0) 
  Passed: ifdef or not 2 (0) 
  Passed: ifdef and and not (0) 
  Passed: ifdef nested 1 (0) 
  Passed: ifdef nested 2 (0) 
  Passed: found elseifdef ABC or FOO (0) 
  Passed: found 2nd elsifdef, second ifdef DEF (0) 
  Passed: sizeof C_POINTER X86_64 (0) 
  Passed: sizeof C_POINTER BITS64 (0) 
  Passed: sizeof C_LONG LONG64 (0) 
---------------------------------------------------------------------------- 
  (Tests: 0018) (Status:  ok) (Failed: 0000) (Passed: 0018) (Time: 0.000000) 
 
t_ifdef-translated 
============================================================================ 
all tests successful 
  Passed: ifdef normal (0) 
  Passed: ifdef not (0) 
  Passed: ifdef and (0) 
  Passed: ifdef or 1 (0) 
  Passed: ifdef or 2 (0) 
  Passed: ifdef or 3 (0) 
  Passed: ifdef and not 1 (0) 
  Passed: ifdef and not 2 (0) 
  Passed: ifdef or not 1 (0) 
  Passed: ifdef or not 2 (0) 
  Passed: ifdef and and not (0) 
  Passed: ifdef nested 1 (0) 
  Passed: ifdef nested 2 (0) 
  Passed: found elseifdef ABC or FOO (0) 
  Passed: found 2nd elsifdef, second ifdef DEF (0) 
  Passed: sizeof C_POINTER X86_64 (0) 
  Passed: sizeof C_POINTER BITS64 (0) 
  Passed: sizeof C_LONG LONG64 (0) 
---------------------------------------------------------------------------- 
  (Tests: 0018) (Status:  ok) (Failed: 0000) (Passed: 0018) (Time: 0.000000) 
 
t_ifdef_const.e 
============================================================================ 
all tests successful 
  Passed: ifdef constant a (0) 
  Passed: ifdef constant b (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_const-bound 
============================================================================ 
all tests successful 
  Passed: ifdef constant a (0) 
  Passed: ifdef constant b (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_const-translated 
============================================================================ 
all tests successful 
  Passed: ifdef constant a (0) 
  Passed: ifdef constant b (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_proc.e 
============================================================================ 
all tests successful 
  Passed: Format of ifdef code (0) 
  Passed: ifdef at beginning of function breaks recursion (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_proc-bound 
============================================================================ 
all tests successful 
  Passed: Format of ifdef code (0) 
  Passed: ifdef at beginning of function breaks recursion (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_proc-translated 
============================================================================ 
all tests successful 
  Passed: Format of ifdef code (0) 
  Passed: ifdef at beginning of function breaks recursion (0) 
---------------------------------------------------------------------------- 
  (Tests: 0002) (Status:  ok) (Failed: 0000) (Passed: 0002) (Time: 0.000000) 
 
t_ifdef_switch.e 
============================================================================ 
all tests successful 
  Passed: ifdef recognizes 'case else' (0) 
---------------------------------------------------------------------------- 
  (Tests: 0001) (Status:  ok) (Failed: 0000) (Passed: 0001) (Time: 0.000000) 
 
t_ifdef_switch-bound 
============================================================================ 
all tests successful 
  Passed: ifdef recognizes 'case else' (0) 
---------------------------------------------------------------------------- 
  (Tests: 0001) (Status:  ok) (Failed: 0000) (Passed: 0001) (Time: 0.000000) 
 
t_ifdef_switch-translated 
============================================================================ 
all tests successful 
  Passed: ifdef recognizes 'case else' (0) 
---------------------------------------------------------------------------- 
  (Tests: 0001) (Status:  ok) (Failed: 0000) (Passed: 0001) (Time: 0.000000) 

Test code is here: http://rapideuphoria.com/structures_v0.2.zip

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

25. Re: wrapping C code - my exercise in incompetence.

Looks like all the tests passed.

jmduro said...

Test code is here: http://rapideuphoria.com/structures_v0.2.zip

Jean-Marc

Can you come up with a simpler test case?

Also, can you file a ticket for this bug?

new topic     » goto parent     » topic index » view message » categorize

26. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...

Can you come up with a simpler test case?

Also, can you file a ticket for this bug?

Hi Jim, I simplified the test case and filed a ticket.

new topic     » goto parent     » topic index » view message » categorize

27. Re: wrapping C code - my exercise in incompetence.

PeteE said...
jimcbrown said...

Can you come up with a simpler test case?

Also, can you file a ticket for this bug?

Hi Jim, I simplified the test case and filed a ticket.

Thanks for doing this.

jmduro said...

It took some time but I finally found where it hurts. OE 4.1 does not manage correctly ifdef statements on Linux (Revision Date: 2013-04-15 or Revision Date: 2015-02-02).

So if I understand the ticket correctly, jmduro is wrong - there is no bug with the ifdefs.

new topic     » goto parent     » topic index » view message » categorize

28. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...
PeteE said...
jimcbrown said...

Can you come up with a simpler test case?

Also, can you file a ticket for this bug?

Hi Jim, I simplified the test case and filed a ticket.

Thanks for doing this.

jmduro said...

It took some time but I finally found where it hurts. OE 4.1 does not manage correctly ifdef statements on Linux (Revision Date: 2013-04-15 or Revision Date: 2015-02-02).

So if I understand the ticket correctly, jmduro is wrong - there is no bug with the ifdefs.

Correct. The ifdef BITS32 in his code prevents the bug on 32-bit platforms, so I can see how it can seem to be ifdef-related.

new topic     » goto parent     » topic index » view message » categorize

29. Re: wrapping C code - my exercise in incompetence.

PeteE said...

Correct. The ifdef BITS32 in his code prevents the bug on 32-bit platforms, so I can see how it can seem to be ifdef-related.

Could you explain please? When I extract the portion between ifdefs, I still don't understand where I have to correct the code because I didn't catch the logic behind ifdef management.

ifdef EU4_0 then 
    case C_INT, C_BOOL, C_LONG, 
         C_HRESULT, C_LPARAM, 
         C_WPARAM then               -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_UINT, C_DWORD, C_HANDLE, 
         C_HWND, C_POINTER, C_SIZE_T, 
         C_ULONG then                -- 32-bit unsigned (#02000004) 
      lg += 4 
elsifdef EU4_1 then 
    case C_BOOL, C_INT then          -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_DWORD, C_UINT then        -- 32-bit unsigned (#02000004) 
      lg += 4 
    case C_DWORDLONG, C_LONGLONG then -- 64-bit integer (#03000002) 
      lg += 8 
  ifdef BITS32 then     -- 32-bit 
    case C_LONG, C_HRESULT then      -- 32-bit signed   (#01000008) 
      lg += 4 
    case C_ULONG, C_SIZE_T then      -- 32-bit unsigned (#02000008) 
      lg += 4 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 32-bit pointer  (#03000001) 
      lg += 4 
  elsifdef BITS64 then  -- 64-bit 
    case C_LONG, C_HRESULT then      -- 64-bit signed   (#01000008) 
      lg += 8 
    case C_ULONG, C_SIZE_T then      -- 64-bit unsigned (#02000008) 
      lg += 8 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 64-bit pointer  (#03000001) 
      lg += 8 
  end ifdef 
end ifdef 
 

In my case, Eu 4.1 on x86-64, the interpreter should see

    case C_BOOL, C_INT then          -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_DWORD, C_UINT then        -- 32-bit unsigned (#02000004) 
      lg += 4 
    case C_DWORDLONG, C_LONGLONG then -- 64-bit integer (#03000002) 
      lg += 8 
    case C_LONG, C_HRESULT then      -- 64-bit signed   (#01000008) 
      lg += 8 
    case C_ULONG, C_SIZE_T then      -- 64-bit unsigned (#02000008) 
      lg += 8 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 64-bit pointer  (#03000001) 
      lg += 8 
 

Do I have to understand that on a 64-bit system, both BITS32 and BITS64 are defined ?

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

30. Re: wrapping C code - my exercise in incompetence.

jmduro said...
ifdef EU4_0 then 
    case C_INT, C_BOOL, C_LONG, 
         C_HRESULT, C_LPARAM, 
         C_WPARAM then               -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_UINT, C_DWORD, C_HANDLE, 
         C_HWND, C_POINTER, C_SIZE_T, 
         C_ULONG then                -- 32-bit unsigned (#02000004) 
      lg += 4 
elsifdef EU4_1 then 
    case C_BOOL, C_INT then          -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_DWORD, C_UINT then        -- 32-bit unsigned (#02000004) 
      lg += 4 
    case C_DWORDLONG, C_LONGLONG then -- 64-bit integer (#03000002) 
      lg += 8 
  ifdef BITS32 then     -- 32-bit 
    case C_LONG, C_HRESULT then      -- 32-bit signed   (#01000008) 
      lg += 4 
    case C_ULONG, C_SIZE_T then      -- 32-bit unsigned (#02000008) 
      lg += 4 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 32-bit pointer  (#03000001) 
      lg += 4 
  elsifdef BITS64 then  -- 64-bit 
    case C_LONG, C_HRESULT then      -- 64-bit signed   (#01000008) 
      lg += 8 
    case C_ULONG, C_SIZE_T then      -- 64-bit unsigned (#02000008) 
      lg += 8 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 64-bit pointer  (#03000001) 
      lg += 8 
  end ifdef 
end ifdef 
 

unrelated to the above, to future proof code a little: instead of checking for EU4_1,
I wonder if that should instead be EU4

euphoria 4.0 will be handled already by the ifdef EU4_0 and at some future time when EU4_2 is defined, the code presumably could still work as expected.

new topic     » goto parent     » topic index » view message » categorize

31. Re: wrapping C code - my exercise in incompetence.

jmduro said...
PeteE said...

Correct. The ifdef BITS32 in his code prevents the bug on 32-bit platforms, so I can see how it can seem to be ifdef-related.

Could you explain please? When I extract the portion between ifdefs, I still don't understand where I have to correct the code because I didn't catch the logic behind ifdef management.

In my case, Eu 4.1 on x86-64, the interpreter should see

    case C_BOOL, C_INT then          -- 32-bit signed   (#01000004) 
      lg += 4 
    case C_DWORD, C_UINT then        -- 32-bit unsigned (#02000004) 
      lg += 4 
    case C_DWORDLONG, C_LONGLONG then -- 64-bit integer (#03000002) 
      lg += 8 
    case C_LONG, C_HRESULT then      -- 64-bit signed   (#01000008) 
      lg += 8 
    case C_ULONG, C_SIZE_T then      -- 64-bit unsigned (#02000008) 
      lg += 8 
    case C_POINTER, C_HANDLE, C_HWND, 
         C_LPARAM, C_WPARAM then     -- 64-bit pointer  (#03000001) 
      lg += 8 
 

On 64bit, C_HANDLE is defined as a C_LONGLONG (#03000002), not as a C_POINTER (#03000001)

See http://scm.openeuphoria.org/hg/euphoria/file/16462e686646/include/std/dll.e#l68 and http://scm.openeuphoria.org/hg/euphoria/file/16462e686646/include/std/dll.e#l64

ne1uno said...

unrelated to the above, to future proof code a little: instead of checking for EU4_1,
I wonder if that should instead be EU4

euphoria 4.0 will be handled already by the ifdef EU4_0 and at some future time when EU4_2 is defined, the code presumably could still work as expected.

Sounds reasonable.

jmduro said...

Do I have to understand that on a 64-bit system, both BITS32 and BITS64 are defined ?

Nope.

new topic     » goto parent     » topic index » view message » categorize

32. Re: wrapping C code - my exercise in incompetence.

In order to avoid what Jeremy Cowgar called a Chicken and Egg problem1, the 4.1 can be translated with 4.0 binaries. That is why there is a sizeof() function defined in the 4.1 source for 4.0. You can copy this function and put it in the source of your program and then replace that switch/case and ifdef combination with:

lg += sizeof(c_type) 

(1) without a working a binary that understands the new syntax you cannot convert the the source code that uses that new syntax into C, and without the translated source in C you cannot compile and get an up to date version of the binary. When the syntax was changing in 4.0.0 development this was a problem.

new topic     » goto parent     » topic index » view message » categorize

33. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...

Now I understand better what's going on. In std/dll.e of my OE 4.1 release (2015-02-13), C_HANDLE is defined as a C_POINTER, not as a C_LONGLONG, both in the 32-bit and 64-bit versions.

	--** handle sizeof pointer 
	C_HANDLE  = C_POINTER, 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

34. Re: wrapping C code - my exercise in incompetence.

jmduro said...

Now I understand better what's going on. In std/dll.e of my OE 4.1 release (2015-02-13), C_HANDLE is defined as a C_POINTER, not as a C_LONGLONG, both in the 32-bit and 64-bit versions.

Something is wrong here. Looking at the hg logs, http://scm.openeuphoria.org/hg/euphoria/log/16462e686646/include/std/dll.e , there was only one change between that date and now, and that was Greg adding a C_ULONGLONG type (which didn't affect C_HANDLE http://scm.openeuphoria.org/hg/euphoria/rev/802120a0fe4e ).

The C_HANDLE change was made in March 2013: http://scm.openeuphoria.org/hg/euphoria/rev/4799252e3ba5

new topic     » goto parent     » topic index » view message » categorize

35. Re: wrapping C code - my exercise in incompetence.

ne1uno said...

[unrelated to the above, to future proof code a little: instead of checking for EU4_1,
I wonder if that should instead be EU4

euphoria 4.0 will be handled already by the ifdef EU4_0 and at some future time when EU4_2 is defined, the code presumably could still work as expected.

If you look a the tables above (#19), you'll see that some variables have different numeric values in 4.05 and 4.1: C_LONG, C_ULONG, etc.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

36. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...
jmduro said...

Now I understand better what's going on. In std/dll.e of my OE 4.1 release (2015-02-13), C_HANDLE is defined as a C_POINTER, not as a C_LONGLONG, both in the 32-bit and 64-bit versions.

Something is wrong here. Looking at the hg logs, http://scm.openeuphoria.org/hg/euphoria/log/16462e686646/include/std/dll.e , there was only one change between that date and now, and that was Greg adding a C_ULONGLONG type (which didn't affect C_HANDLE http://scm.openeuphoria.org/hg/euphoria/rev/802120a0fe4e ).

The C_HANDLE change was made in March 2013: http://scm.openeuphoria.org/hg/euphoria/rev/4799252e3ba5

I see. My executables ared dated 2015-05-20 but the include files are dated 2012-08-26.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

37. Re: wrapping C code - my exercise in incompetence.

jimcbrown said...
PeteE said...
jimcbrown said...

Can you come up with a simpler test case?

Also, can you file a ticket for this bug?

Hi Jim, I simplified the test case and filed a ticket.

Thanks for doing this.

jmduro said...

It took some time but I finally found where it hurts. OE 4.1 does not manage correctly ifdef statements on Linux (Revision Date: 2013-04-15 or Revision Date: 2015-02-02).

So if I understand the ticket correctly, jmduro is wrong - there is no bug with the ifdefs.

I will correct my code. However, ifdefs (or switch statement) still have a bug. This is not allowed:

switch def[i] do 
ifdef EU4_0 then  -- error if ifdef follows immediatly switch statement 
  case C_LPARAM, C_WPARAM then 
    free(values[i]) 
elsifdef EU4_1 then 
  case C_LONG_PTR, C_HANDLE, 
       C_HWND then                 -- 32-bit signed   (#01000008) 
    free(values[i]) 
end ifdef 
end switch 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu