IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New C Structure Question
I'm trying out [link|http://www.jniwrapper.com/index.jsp|JNIWrapper] to get rid of hand coded Windows JNI C code in my Java application. So far it's worked great, but I'm having a little trouble with a structure. This structure supplies parameters to the Sybase ASA dbbackup command. The structure looks like this:
\n#if defined(__unix) || defined(_AIX)\n    #if !defined(a_bit_field)\n        #define a_bit_field unsigned int\n        #define a_bit_short unsigned int\n    #endif\n#else\n    #if !defined(a_bit_field)\n        #define a_bit_field unsigned char\n        #define a_bit_short unsigned short\n    #endif\n#endif\ntypedef struct a_backup_db {\n    unsigned short\tversion;\n    const char _fd_\t*output_dir;\n    const char _fd_\t*connectparms;\t// userid,password,database\n    const char _fd_\t*startline;\t\t// (NULL for default start line)\n    MSG_CALLBACK\tconfirmrtn;\n    MSG_CALLBACK\terrorrtn;\n    MSG_CALLBACK\tmsgrtn;\n    MSG_CALLBACK\tstatusrtn;\n    a_bit_field\t\tbackup_database\t: 1;\n    a_bit_field\t\tbackup_logfile\t: 1;\n    a_bit_field\t\tbackup_writefile: 1;\t// only if using write file\n    a_bit_field\t\tno_confirm\t: 1;\n    a_bit_field\t\tquiet\t\t: 1;\n    a_bit_field\t\trename_log\t: 1;\n    a_bit_field\t\ttruncate_log\t: 1;\n    a_bit_field\t\trename_local_log: 1;\n    const char _fd_\t*hotlog_filename;\n    char\t\tbackup_interrupted;\n} a_backup_db;\n

I'm a bit confused by the bit field definitions. What does it mean when a structure field is followed by ": 1"?

I also have an issue where JNIWrapper only has a signed Char field, no unsigned char. I need to set some values to 1. Does a uchar = 1 map to a char = 1, or do I need to do some converting?

Thanks,
John
New Re: C Structure Question
So how does the product compare to regular JNI? Is it faster or slower?

Is the only reason to use it simplicity?
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Re: C Structure Question
I haven't noticed any speed difference, but we don't use JNI for any speed critical stuff. It's mostly used for accessing OS specfic APIs and functions in 3rd party DLLs and ActiveX controls.

It's definitly much simpiler. I can get rid of the seperate Visual C++ projects and also simplify my ANT scripts by using this. If I can figure out this last structure issue, the only JNI code I'll have left is in the PowerBuilder to Java integration module, which has to stay in C code because of PowerBuilder.
New :1 allows you to pack multiple members in one word
So you have something that is equivalent to an int (or a char/a short), but only takes one bit. Not a bad way to represent booleans.

The drawbacks: can't take an address of this thing, and you have no idea how the compiler actually packed the fields. And, it's probably much slower, too. It's been ages since I last saw this used. Correction - may be I never saw this used.

[link|http://www.open-std.org/jtc1/sc22/open/n2356/|http://www.open-std..../sc22/open/n2356/]

search for class.bit

------

179. I will not outsource core functions.
--
[link|http://omega.med.yale.edu/~pcy5/misc/overlord2.htm|.]

New Yuck...
Looks like I won't be accessing that from JNI Wrapper...

Thanks for the info
New Read the Cocoa headers
and you'll find bit fields all over NSWindow and other UI components.

Of course, those headers have been around for a very long time (1987 at least).



"Whenever you find you are on the side of the majority, it is time to pause and reflect"   --Mark Twain

"The significant problems we face cannot be solved at the same level of thinking we were at when we created them."   --Albert Einstein

"This is still a dangerous world. It's a world of madmen and uncertainty and potential mental losses."   --George W. Bush
New Re: much slower, too
Not necessarily. It depends on the code and optimization. If for example you have successive tests (i.e. nested IFs or complex condition) that use the variables sharing a byte or int some economies are possible.

Suppose you had two booleans sharing a byte:

x bxxxxxxx -- where b is the bit for that boolean and likewise
y xbxxxxxx

With a single fetch from memory (with a LOAD machine instruction) you can put both variables in a CPU register. With a single "AND IMMEDIATE" instruction (with 11000000) you can set the "condition code" for the JUMP instruction that tests the condition. That would be handy if you had

if ( x | y )...

Otherwise, the variables need to be loaded and tested separately requiring a larger number of machine instructions and more execution time.

When these variables are unrelated in the code, then indeed time might be wasted by the need to isolate or extract the needed bits from the cohabitants.

Frankly, this kind of thinking should be a thing of the past except for embedded applications with limited resources, e.g. controlling an electric toothbrush. :)
Alex

The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt. -- Bertrand Russell
New Well, embedded applications, yes...
...but not for the reasons you state.

One of the best uses for bit fields is setting/getting hardware registers that have an annoying tendency to pack several command and/or status bit fields of varying length into a single 8-, 16-, or 32-bit register. Most of you web services types (not meant perjoritavely) are so far away from the hardware you never have to mess with such stuff (and probably good riddance, from your perspective, no?). However, even on 32-bit embedded processors (note: over 50% of new embedded designs are with 32-bit processors), bit fields most definitely have their place.

They are also useful for packing data into communication streams. But one must remember that bit fields are explicitly non-portable, so using them to communicate between dissimilar architectures, or even similar architectures with differernt compilers, is more than a bit tricky.
jb4
shrub\ufffdbish (Am., from shrub + rubbish, after the derisive name for America's 43 president; 2003) n. 1. a form of nonsensical political doubletalk wherein the speaker attempts to defend the indefensible by lying, obfuscation, or otherwise misstating the facts; GIBBERISH. 2. any of a collection of utterances from America's putative 43rd president. cf. BULLSHIT

New Re: "not for the reasons you state"
What I had in mind was something like Motorola 6802 (perhaps before your time :)), an 8-bit microprocessor with 128 BYTES of on chip RAM. You would put your code on a separate ROM chip of say 8 KB, but all you had was that measly 128 bytes for memory. So packing bits in bytes was mandatory.
Alex

The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt. -- Bertrand Russell
New I'll see your 6802...
...and raise you an Intel 8748: 64 BYTES of on-chip RAM (which also included the two register sets and the stack...oh, wait a minnit-that 64 BYTES was the stack... and 2KB of on-chip EEPROM. Used it to make an IEEE-488 interface controller for light-pipe data acquisition controllers for an EMP measurement system.

And no, it is definitely not before my time... ;-).
jb4
shrub\ufffdbish (Am., from shrub + rubbish, after the derisive name for America's 43 president; 2003) n. 1. a form of nonsensical political doubletalk wherein the speaker attempts to defend the indefensible by lying, obfuscation, or otherwise misstating the facts; GIBBERISH. 2. any of a collection of utterances from America's putative 43rd president. cf. BULLSHIT

New :-)
Alex

The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt. -- Bertrand Russell
New Re: :1 allows you to pack multiple members in one word
Actually, it defines the number of bits that the field (a.k.a. member) will occupy. If several fields with this :n specification will fit into a storage unit (generally, an int), then the compiler, at its discretion, and according to its own rules, can pack several of these fields into the same storage unit. Note that the ANSI standard leaves the rules of how these things are packed up to the "implementation" (that is, the compiler), so bit fields are specifically not portable. If you are going to back up things from one type of machine and restore them on another, do not even think of using bit fields as part of the back-up format.

SpiceWare is right, in that the number that follows the colon can be something other than one. The number determines how many bits to reserve in the storage unit for that field. The number cannot be greater that the size of the storage unit., so you can't say something like:
\nstruct big_ass\n{\n   unsigned int   super_long_int:128;\n};\n\n
Also, as someone else here said, you cannot take the address of a bit field; the compiler will not take kindly to such an attempt.

Finally, the field must still have a type. The ANSI standard requires the implementation to support all the integer types, but does not require the implementation to actually only reserve that sized storage unit for it. For example, the compiler is supposed to accept something like:
\nstruct its_OK\n{\n   unsigned char   a_field:4;\n   unsigned char   a_nother_field:5;\n};\n

But you cannot assume that the size of the structure is 2 bytes. (Since 9 bits have been allocated, the structure cannot fit into a single byte.) It can legally be as large as 8 bytes (on a 32-bit machine).

HTH...
jb4
shrub\ufffdbish (Am., from shrub + rubbish, after the derisive name for America's 43 president; 2003) n. 1. a form of nonsensical political doubletalk wherein the speaker attempts to defend the indefensible by lying, obfuscation, or otherwise misstating the facts; GIBBERISH. 2. any of a collection of utterances from America's putative 43rd president. cf. BULLSHIT

New more than 1 bit is possible too
[link|http://www.cs.cf.ac.uk/Dave/C/node13.html|http://www.cs.cf.ac....ave/C/node13.html]
\nstruct packed_struct {\n\t\t unsigned int f1:1;\n\t\t unsigned int f2:1;\n\t\t unsigned int f3:1;\n\t\t unsigned int f4:1;\n\t\t unsigned int type:4;\n\t\t unsigned int funny_int:9;\n} pack;

Here the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4 bit type and a 9 bit funny_int.
Darrell Spice, Jr.                      [link|http://spiceware.org/gallery/ArtisticOverpass|Artistic Overpass]\n[link|http://www.spiceware.org/|SpiceWare] - We don't do Windows, it's too much of a chore
New It does work with JNIWrapper!
After a quick e-mail to the folks at JNIWrapper, I found out how to do this. I was missing the Pointer wrappers around strings in the structure and I didn't pack the structure. Once I did that, it worked! It even supports the callbacks!

Here's the code in case you're interested:
\nUShortInt version = new UShortInt(7000);\nAnsiString output_dir = new AnsiString("c:\\tmp");\nconnectparms = new AnsiString("uid=<...>;pwd=<...>;dsn=<...>");\nAnsiString startline = new AnsiString("");\nConfirmCallback confirmrtn = new ConfirmCallback();\nErrorCallback errorrtn = new ErrorCallback();\nMessageCallback msgrtn = new MessageCallback();\nStatusCallback statusrtn = new StatusCallback();\nChar bitFields = new Char((char) 15); // flags are 00001111\nAnsiString hotlog_filename = new AnsiString();\nChar backup_interrupted = new Char();\n\nStructure backup_info = new Structure(new Parameter[] {\n   version,\n   new Pointer(output_dir),\n   new Pointer(connectparms),\n   new Pointer(startline),\n   confirmrtn,\n   errorrtn,\n   msgrtn,\n   statusrtn,\n   bitFields,\n   new Pointer(hotlog_filename),\n   backup_interrupted }, (short) 1);\n\nErrorCallback dbtinfo_errorrtn = new ErrorCallback();\nStructure dbtinfo = new Structure(new Parameter[] {dbtinfo_errorrtn});\n\nLibrary dbtool = new Library("dbtool7.dll");        \nFunction dbbackup = dbtool.getFunction("_DBBackup@4");\nFunction dbtoolsinit = dbtool.getFunction("_DBToolsInit@4");\nFunction dbtoolsfini = dbtool.getFunction("_DBToolsFini@4");\n\t\t\ndbtoolsinit.invoke(null, new Pointer(dbtinfo));\ndbbackup.invoke(null, new Pointer(backup_info));\ndbtoolsfini.invoke(null, new Pointer(dbtinfo));\n\nconfirmrtn.dispose();\nerrorrtn.dispose();\nmsgrtn.dispose();\nstatusrtn.dispose();\ndbtinfo_errorrtn.dispose();
And here is a sample callback (they are all the identical with different class names):
\n/*\n extern short _callback ErrorCallBack(char far * str);\n*/\nclass ErrorCallback extends Callback {\n   private ShortInt result = new ShortInt();\n   private AnsiString message = new AnsiString();\n   public ErrorCallback() {\n      init(new Parameter[] { new Pointer(message) }, result);\n   }\n   public void callback() {\n      System.out.println("ErrorCallback -> " + message);\n      result.setValue(0);\n   }\n} 
This means the only JNI I need in my application is the PowerBuilder to Java bridge. I just got rid of a whole bunch of C code with this thing!
     C Structure Question - (johnu) - (13)
         Re: C Structure Question - (admin) - (1)
             Re: C Structure Question - (johnu)
         :1 allows you to pack multiple members in one word - (Arkadiy) - (8)
             Yuck... - (johnu)
             Read the Cocoa headers - (tuberculosis)
             Re: much slower, too - (a6l6e6x) - (4)
                 Well, embedded applications, yes... - (jb4) - (3)
                     Re: "not for the reasons you state" - (a6l6e6x) - (2)
                         I'll see your 6802... - (jb4) - (1)
                             :-) -NT - (a6l6e6x)
             Re: :1 allows you to pack multiple members in one word - (jb4)
         more than 1 bit is possible too - (SpiceWare)
         It does work with JNIWrapper! - (johnu)

Yeah, let's watch the lamp. It's more fun and less predictable.
123 ms