Solved

c++ written dll

Posted on 2000-02-15
13
227 Views
Last Modified: 2010-04-04
i have a 3rd party c++ written dll. I have the source code and header files for 16 bit of the dll, but i don't have any documentation or header file for the 32 bit one. For a function, in 16 bit header it says:

int FAR PASCAL CallC2 (LPSTR par1,LPSTR par2, LPSTR par3, LPSTR cmd, LPSTR par4) ;

i supposed 32 bit version will have the same type, so i declared it in delphi application as:

 function CallC2 (par1,par2,par3:pchar;par4:pointer):integer;
        cdecl;external 'g:\dll3011\file01.dll' index 5;

The dll is for some socket connection to a unix OS for db connection. You typically allocate some memory first, send some information and the address for the allocated memory(in par4), and can see the results in the par4 parameter address.
my program sends this information, gets the function result successfully however when i try to end up with end parameter in the code, it gives access violation error. Is it something to do with shared memory, or parameters, or ??? Can you please help??

0
Comment
Question by:febalci
  • 4
  • 3
  • 2
  • +3
13 Comments
 
LVL 27

Expert Comment

by:BigRat
ID: 2523503
The four parameters in the 16-bit version are of the same type; but your 32-bit one has the last parameter different.
   One technique is to allocate (or just reference) memory with a fixed pattern (hex 0a0a0a0a0 or whatever), pass this to the function and just printout the memory areas upon return. If the fourth parameter is not what it seems you'll either see what it replies with or you'll get an acess violation with your pattern (address 0x0a0a0a0a).
0
 
LVL 3

Expert Comment

by:Alisher_N
ID: 2523994
it is definitely a problem with wrong declaration...

first of all show us real declaration in *.h and your code in Delphi

secondary, try to replace 'par4:pointer' with 'var par4', this probably will help
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2524626
You have missed out a paramter, change it to this:

function CallC2 (par1,par2,par3,cmd:pchar;par4:pointer):integer;
        cdecl;external 'g:\dll3011\file01.dll' index 5;

You should probably change the type of par4 to a PChar to be consistent with the others.

Also, make sure the calling convention (cdecl) matches the DLL calling convention.

Cheers,

Raymond.
0
ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

 

Author Comment

by:febalci
ID: 2525929
Well rwilson, i tried pchar for par4, it didn't worked. i also tried stdcall and safecall too. They all failed.
Alish, i tried that var thing too. Upon return, the address changes, but neither the old address, nor the new one doesn't contain the data.
in fact the real declarations are as follows:

int FAR PASCAL CallC2 (LPSTR req_id,LPSTR dest1, LPSTR dest2, LPSTR cmd, LPSTR object,
                LPSTR seq, LPSTR tws, LPSTR twe, LPSTR selection, LPSTR fields,
                LPSTR data, LPSTR data_dest) ;


and in my application:

    function CalC2 (_req_id,_dest1,_dest2,_comand,_table,_order,_tws,_twe,_selektion,_fields:pchar;var _data:pointer;_destbuf:pchar):integer;
        cdecl;external 'g:\dll3011\file01.dll' index 5;

When i check out the network, i see that the socket connection is made, the SQL request is sent, and the reply has been get, but however the reply is not on the required address and then i get the access violation.

in 16 bit version source code, the point which i guess as making an access violation is that it gives data[0]=/0 line. data is declared as LPSTR in the dll, not an array and i really didn't understand what data[0] means. (Btw i'm not good in c++ as you can see).
Thanx.


0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2525981
Your last two paramters should not be var. That will be causing a problem as the wrong pointer values are being passed to the DLL.

data[0] is refering to the first byte pointed to by data (it's just the way pointers to things and arrays are essentially the same things in C/C++).

data[0] = /0; means assign the char value 0 to item index 0.

Cheers,

Raymond.
0
 
LVL 3

Expert Comment

by:Alisher_N
ID: 2526440
sorry, I made a mistake above...
try to declare in pascal as
....;var somedata;...
without any type, so when you call this function use
...., mybuffer_fordata,...
pascal will send an address of your buffer, in C DLL it is expecting a pointer, so they have to match now...
(actually LPSTR = ^Char; in C)

if it not working again ;-) please tell us exactly what params are IN and what are OUT in C function - I am not sure... common rule is OUT parameters should be declared with 'var' so their passed by reference

also try to declare in pascal with different convention (cdecl, stdcall, etc... ) because you are not sure if 16-bit header the same in 32-bit

0
 

Expert Comment

by:brunohe
ID: 2526455
Don't cast the parameters as PChar but do the following:

var
  pPar1: PChar;
begin
 
  GetMem(pPar1, Length(sString1));
  StrPCopy(pPar1, sString1);
 
  YourCall(pPar1);

  FreeMem(pPar1, Length(sString1));
end;

I had a lot of problems with casting Strings as PChar. The only solution was to declare a PChar and copy the string with StrPCopy. Don't ask me why it don't worked...
0
 
LVL 3

Expert Comment

by:Alisher_N
ID: 2526573
there is simpler solution to this, brubohe:

var
  MyBuf : Array[0..1023 {or something} ] of Char;
  s1 : String;
begin
  call_pchar_needed_function( MyBuf );
  s1 := String( MyBuf );
  { or }
  ShowMessage( String( MyBuf ));
end.
0
 

Expert Comment

by:kser
ID: 2526969
 IMHO, trying to use undocumented DLL, you're playing in a very risky game (casino always wins ;-). Maybe the better (and simpler, and faster) way is to write simple thunk to well-defined 16-bit DLL ? It's really simple, you just need to obtain a free Microsoft's thunk compiler or use undocumented function QT_Thunk from kernel32.dll. I did it by the second way and all works very stable. There was a very impressive article in "The Delphi Magazine" (jan'98) by Brian Long with huge set of samples. You may find it on www.itecuk.com.
0
 
LVL 27

Accepted Solution

by:
BigRat earned 100 total points
ID: 2532481
All the parameters to the function are LPSTR which means "long pointer to c-string" in other words long pointer to an (packed) array of characters whose lower bound is zero. In every parameter posaition the function expects an array of characters. Therefore ALL of the Delphi parameters must be PChar and you must feed the function with real arrays :-
   p1 : array[0..n1] of Char;
   p2 : array[0..n2] of Char;
   p3 : array[0..n3] of Char;
   p4 : array[0..n4] of Char;
   .............

   CallC2(PChar(@p1[0]),
          PChar(@p2[0]),
          ....);
is a somewhat cumbersome way of doing it but perfectly compatible with the specification. Do not declare a variable as PChar and pass that - since there is NO DATA BEHIND IT and it will crash.

PS: Brunohe: Delphi DIRECTLY supports casting Delphi long strings to PChar so as to be compatible with C. I have had absolutely no problems in this area.
0
 

Author Comment

by:febalci
ID: 2534507
Well thunking caused a lot more trouble. And it didn't solved my problem. Thanx
0
 

Author Comment

by:febalci
ID: 2534511
Well thunking caused a lot more trouble. And it didn't solved my problem. Additionally i'm trying to make it work on NT. As far as i learned generic thunks don't allow to use 32 bit code with 16 bit dll.
But anyway, thanx.
0
 

Author Comment

by:febalci
ID: 2534519
strange bu it worked. Thanx to everyone who commented and answered.
0

Featured Post

Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question