Okay, you C types: This seems pretty straight forward to translate:
Okay, you C types: This seems pretty straight forward to translate:
short GeoEngCheckDbAvailability(char *pSearchPath,
char *pDbName,
char *pUserDictionaryPath,
short *pDbFlags);
But the translation I have is:
function GeoEngCheckDbAvailability(pSearchPath: PAnsiChar; pDbName: PAnsiChar; pUserDictPath: PAnsiChar; pDbFlags: pshort): short;
seems to be causing problems, specifically AV's.
Help?
short GeoEngCheckDbAvailability(char *pSearchPath,
char *pDbName,
char *pUserDictionaryPath,
short *pDbFlags);
But the translation I have is:
function GeoEngCheckDbAvailability(pSearchPath: PAnsiChar; pDbName: PAnsiChar; pUserDictPath: PAnsiChar; pDbFlags: pshort): short;
seems to be causing problems, specifically AV's.
Help?
I'm not really a c type, but what about your calling convention? Don't you need to append ;cdecl, or are you just not showing that in your code snippet?
ReplyDeleteOh, sorry -- the declaration is stdcall;
ReplyDeleteTGeoEngCheckDbAvailability = function(pSearchPath: pAnsichar; pDbName: PAnsiChar; pUserDictPath: PAnsiChar; pDbFlags: pshort): short; stdcall;
ReplyDeleteI wouldn't know. I'm a normal person and don't understand cruddy languages to translate. ;-)
ReplyDeleteI should add that this works fine in our D7 code base and I'm now having troubles in XE3. I changed the PChars all to be PAnsiChars in the XE3 version.
ReplyDeleteDumb question: Have you looked in Windows.pas for similar?
ReplyDeleteGood idea --
ReplyDeleteI searched, and can't seem to find a similar construct.
Nick Hodges It's been a while, and I haven't had to mess with that stuff since D7, in fact, but in XE's Windows.pas, I see this:
ReplyDeleteLPCTSTR = {$IFDEF UNICODE}PWideChar{$ELSE}PAnsiChar{$ENDIF};
So, just for fun, what if you do this:
function GeoEngCheckDbAvailability(pSearchPath: LPCTSTR; pDbName: LPCTSTR; pUserDictPath: LPCTSTR; pDbFlags: pshort): short;
If it makes a difference, then I would anticipate that PWideChar is being applied....
Nick Hodges It is likely that the implementation is in a DLL. If the DLL is using AnsiChar, then the translation you have is correct (Add calling convention). You cannot pass PChar (unicode) if the DLL expect ASCII characters.
ReplyDeleteYou may want ot build a wrapper to translate between ASCII (ansi) and unicode which will be easier to use in the application.
The weird thing is that it throws the AV's, but then it works.
ReplyDeleteProbably a calling convention issue. Do you have the original C source code (The .H file) ?
ReplyDeleteThat's the thing -- it works fine with stdcall in Delphi 7.
ReplyDeleteThe plot thickens: If I run the EXE outside of the debugger, I see no AVs.
I am trying to track down the original *.h file....
ReplyDeleteTDump is your friend. Run TDump against the DLL with -ea parameter. Save to a convenient text file, then go spelunking.
ReplyDeleteThat was the next step.
ReplyDeleteWhen I did have to this stuff, TDump was a lifesaver. I also found it essential to have a unit which provided the conversion of all DLL funcs to Delphi versions, and did so in a way that gave me useful debug info. For one thing, you are then working against the exported calls, not what a doc claims they are....
ReplyDeletei once had an issue with a DLL. It seems to work, but not always... The problem was that the DLL was using cdecl calling convention. try it!
ReplyDeleteI can't seem to get TDump to tell me anything about parameters on the exports.....
ReplyDeleteI can try to dig out some old dump files. As I recall, though, TDump will give you a byte count for the parameters. As the call you specified is passing 5 pointers, then there should be 20 bytes of parameters. As Francois said, though, the calling convention can be an issue. Try changing to cdecl, which is the common C convention, and see whether the AVs go away. I can't offer a reason why it would be fine on D7, and not on XE3, however.
ReplyDeleteNick Hodges I have located an old (TDump) export in which there are multiple sets of exported function specs. This is from a DLL which originally exported C++ classes (don't ask), then added plain C style funcs and also numerically indexed functions. In the C style functions, I see at the end of the name an @ followed by a number: MyFunc@20, for example. I'm sorry, but I do not know whether this is a common format, as I worked long term with only a few DLLs.
ReplyDeleteRun this in D7 in debugger, check the ASM code to see how parameters are pushed; repeat the drill in XE3.
ReplyDeleteJust a hint: try to debug both cases in D7 & XE3 with OllyDBG to figure out the difference.
ReplyDeleteBTW, changing to cdecl locked everything up really badly.....
ReplyDeleteNick Hodges Then that's not the issue. ;) But at least now you know! I didn't ask before, but you are building for 32-bit, right?
ReplyDeleteYeah, this is all 32-bit.
ReplyDeleteOK, it only occurred to me a short time ago that on XE3 there was the potential for complexities well beyond any experience I can claim.
ReplyDeletePrimož Gabrijelčič My CPU Window skills are fairly limited, so here's the picture from D7 --
ReplyDeleteWell, you can't put a picture in a comment, so I'll try it in a new message....
To put a picture in a comment - upload to G+ and paste link.
ReplyDeleteCould some of the parameters be var v:type instead of v:ptype ?
ReplyDeleteNick Hodges re: screenshots in comments. That's why I really like the screen shot annotation utility called Clarify (mac and windows versions).
ReplyDeleteCheck out the shot I made of this conversation, with some annotations, including highlighting, blurring, arrows, text, etc. Took about 1 minute.
http://trident.clarify-it.com/d/mgg436
(Click image to zoom)
It's easy to use, but best of all you get free webspace to post your shots to a customizable page, directly from the Clarify application. You can also export to HTML, PDF to file or email, and EverNote.
Very handy for both giving and receiving support, especially in situations where you can't post a screen shot directly. e.g. web form support mail, G+ comments, etc.
http://www.clarify-it.com/
Trace the declaration of pshort. I might not be what you think.
ReplyDelete^ Yes I was going to suggest using Integer (or Smallint) instead if Short in your Delphi declaration.
ReplyDeleteshort is declared as:
ReplyDeletetype
short = word;
pshort = ^short;
So am I off base saying the C would actually have to be:
ReplyDeleteunsigned short GeoEngCheckDbAvailability(char *pSearchPath,
char *pDbName,
char *pUserDictionaryPath,
unsigned short *pDbFlags);
I don't suppose that is all that important but it's more correct. Maybe your short should be type Smallint not Word.
I found the API you are using. Downloaded the sample programs and compiled using MSVC. here is the result for the generated code:
ReplyDelete; 143 : /*
; 144 : * Check availability, we only initialize if STREET_DB and CENTROID_DB
; 145 : * ara available.
; 146 : */
; 147 : retCode = GeoEngCheckDbAvailability (dbPath, dbName, NULL, &dbFlags);
002fa 8d 85 c8 fe ff
ff lea eax, DWORD PTR _dbFlags$[ebp]
00300 50 push eax
00301 6a 00 push 0
00303 8b 8d f8 fe ff
ff mov ecx, DWORD PTR _dbName$[ebp]
00309 51 push ecx
0030a 8d 95 fc fe ff
ff lea edx, DWORD PTR _dbPath$[ebp]
00310 52 push edx
00311 ff 15 00 00 00
00 call DWORD PTR __imp__GeoEngCheckDbAvailability@16
00317 66 89 85 cc fe
ff ff mov WORD PTR _retCode$[ebp], ax
; 148 : if (retCode != SUCCESS)
In the sample program, I see dbPath is déclared as an array of 256 chars. Maybe this is important. dbName is just a char* so no storage except the exact character number. dbFlags is a short.
sizeof(short) is 2, so it is a 16 bit integer.
François Piette Well, that was above and beyond. ;-)
ReplyDeleteI'll try playing around with dbPath as and array of ansichar.
Nick Hodges Also, I have found in the past that some of these DLL calls will fail unless I FillChar the entire byte array with 0 before calling.
ReplyDeleteBill -- Good idea, but that didn't help either. ;-)
ReplyDeleteThe VB example below uses integer instead of short for the flag parameter. You might try that.
ReplyDeletehttp://testdrive.mapinfo.com/TECHSUPP/MIPROD.NSF/e08b144fde30853f8525712500685756/1ab355b9012246b58525677b0072c2ec?OpenDocument
Nick Hodges Man, you just won't make it easy, will you? ;) Which compiler are you on?
ReplyDeleteXE3
ReplyDeleteIman Crawford I changed the declaration of short to be a smallint. Didn't help. ;-)
ReplyDeleteNick Hodges Oh well. Don't have it, else I would volunteer to fight with it myself. I can't believe that none of the suggestions have gotten you to a solution. Whose DLL is this?
ReplyDeletetry 32 bit integer. I noticed there is a mm16*.dll and mm32*.dll. Maybe the documentation is wrong.
ReplyDeleteIman --
ReplyDeleteThanks for helping out --
I only have the mm32v12.dll on my hard drive.
Iman -- Great sample code, by the way.
ReplyDeleteFrom another sample at that sight, the right parameter is declared as:
char *search_path, char *db_name
which is exactly what I'm doing.
Very, very weird.
How do you load the function?
ReplyDeleteImplicit via index or name, or explicit?
I guess you already checked if you had the right index?
BTW, Isn't there an OLE Automaton version of this as well?
ReplyDeleteCould it be expecting OLE types?
It's all dynamic, using LoadLibrary and GetProcAddess.
ReplyDeleteThe weird thing is that it all works despite the AV.
That is weird - perhaps the AV is "data driven" ?
ReplyDeleteNick Hodges Huh? What if you pass in the third param as a zero-filled array, instead of the nil?
ReplyDeleteYou could reduce the D7 project to its simplest compilable project, upload it somewhere and let us figure it out... ;o) provided the DLL that house the GeoEngCheckDbAvailability is not some commercial product...
ReplyDelete