digitalmars.D.learn - MySQL connection strange behavior (again...)
- miazo (71/71) Feb 22 2012 Hello,
- Adam D. Ruppe (3/4) Feb 22 2012 This should be extern(System), not extern(C). My
- miazo (19/19) Feb 22 2012 Thank you for that suggestion but I have tried it before -
- Mars (2/2) Feb 22 2012 He said System, as in literally System, not System as in your
- miazo (4/4) Feb 22 2012 Well, on http://dlang.org/attribute.html I can read that "System
- Adam D. Ruppe (5/7) Feb 22 2012 I think the /s switch is needed on that one when doing the
Hello, I'm facing a strange problem(s) with connecting from D to MySQL database under Windows XP. I've read almost everything on this newsgroup concerning database connectivity, I've checked D libraries written by others, I've read MySQL documentation on its C API, I searched other sites for similar problems and still I have no clue what's going on. Perhaps it's something really trivial? So, here is what I have done: - I have MySQL database (version 5.5.20) running on localhost (I can query it without any problems with its command line tool, so it's OK). - I converted libmysql.dll to libmysql.lib with implib.exe tool with /system option and put resulting libmysql.lib file in windows\lib directory of DMD compiler. - The following test code: pragma(lib, "libmysql"); extern (C) { alias void MYSQL; MYSQL* mysql_init(MYSQL* mysql); } void main() { MYSQL* c = mysql_init(null); } compiles and runs but ends with object.Error: Access Violation message. The "strange" part is that: - mysql_init function runs fine - as I understand its purpose, it just allocates memory for MySQL connection and I can check that it returns a not-null pointer - If I put mysql_init in another function like: pragma(lib, "libmysql"); extern (C) { alias void MYSQL; MYSQL* mysql_init(MYSQL* mysql); } MYSQL* init() { return mysql_init(null); } void main() { MYSQL* c = init(); } the program runs without any error message. My guess is that it's something I'm doing wrong with binding from C but I have no idea what it can be exactly, as: - I have come exactly the same way (i.e. C bindings + making of .lib file) with connecting to SQLite, Postgres and via ODBC and I have not encounter such problems (I can connect and execute queries). - I can actually connect to MySQL and execute queries - the above example is simplified. But as I work with MySQL database I see more and more strange behavior, for instance: I use a variable to store number of fields in a result (mysql_num_fields function gives me that) and when I later want to get that number I see something like 18454345 (but earlier it was just: 2 fields). So it looks like something have corrupted the memory where I put my data? Can it be GC (but I have no such problems with other DB engines)? Or is it MySQL library? The most annoying part is that very often I can't reproduce the problem - simply changing the order of two commands in a program can fix or brake it. - There was a known problem with unsigned long in MySQL bindings but what I'm using is just uint. - Maybe it has something to do with the database encodings? But my database uses utf-8 and I set it to utf-8 for session just after opening a new connection (with mysql_set_character_set function). Thank you for your help and any ideas that can help me to debug it further. PS. I am aware of the fact that there are (were?) efforts to make a common database library for D; nonetheless I just wanted to learn D and as I have database background writing that kind of library seemed most familiar to me.
Feb 22 2012
On Wednesday, 22 February 2012 at 12:06:42 UTC, miazo wrote:extern (C) {This should be extern(System), not extern(C). My guess is that's causing most your problems.
Feb 22 2012
Thank you for that suggestion but I have tried it before - changing extern (C) to extern (Windows) gives me a linker error: Error 42: Symbol Undefined _mysql_init 4 As I wrote, I have libmysql.lib in a proper DMD folder and I can see that _mysql_init function is defined inside. I have tried two versions of libmysql.lib that I could create: the one made from original libmysql.lib from MySQL installation converted with coffimplib utility, and the other one made from libmysql.dll with implib utility. Both versions compile if I stay with extern (C) instead of extern (Windows). I was wondering if this is really necessary? Sqlite bindings, for example, use extern (C) without problems. If it is, how do I get rid of that linker error? On the other hand, I have found this bug: http://d.puremagic.com/issues/show_bug.cgi?id=3342 which is marked as FIXED. But as I read the full description linked there I have that feeling that this is what I observe when I work with MySQL database (but why it is not the case with Sqlite or Postgres?). Can it be verified somehow or is there some workaround?
Feb 22 2012
He said System, as in literally System, not System as in your System. Your example works fine for me with that.
Feb 22 2012
Well, on http://dlang.org/attribute.html I can read that "System is the same as Windows on Windows platforms, and C on other platforms". BTW, under which Windows version did you check?
Feb 22 2012
On Wednesday, 22 February 2012 at 17:02:01 UTC, miazo wrote:Error 42: Symbol Undefined _mysql_init 4 libmysql.dll with implib utility.I think the /s switch is needed on that one when doing the mysql libraries on implib. /s changes what's done with the _ in the front. I've done this before but don't remember exactly what I did though.
Feb 22 2012
Yes, /s or /system is a switch that appends _ in front of names from a .dll file. This is exactly how I've used implib.
Feb 22 2012
Problem solved. :-) I found that it was 4 suffix that was missing. With a libmysql.def file as below: LIBRARY libmysql EXETYPE NT SUBSYSTEM WINDOWS EXPORTS _mysql_init 4 = mysql_init I was able to generate working libmysql.lib file with implib (with /system switch). That, with changing from extern (C) to extern (System), removed the problematic issue. Thank you for all your hints!
Feb 22 2012
On Wednesday, 22 February 2012 at 21:18:32 UTC, miazo wrote:Problem solved. :-) I found that it was 4 suffix that was missing. With a libmysql.def file as below: LIBRARY libmysql EXETYPE NT SUBSYSTEM WINDOWS EXPORTS _mysql_init 4 = mysql_init I was able to generate working libmysql.lib file with implib (with /system switch). That, with changing from extern (C) to extern (System), removed the problematic issue. Thank you for all your hints!You shouldn't have to manually create a .def file. Try using coffimplib (I think it's bundled with dmc?) instead of implib and use it on libmysql.lib (coffimplib libmysql.lib _libmysql.lib, back up the original libmysql.lib, replace the original with the generated _libmysql.lib, and then link to it). Then create your headers with extern(System). It seems that adding it manually into the .def file is working for you, but it's a lot more effort than needed.
Feb 22 2012
You are right, coffimplib with -e switch does it.
Feb 23 2012