Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- From: "Paul Soper" <paul_soper@xxxxxxxxxxx>
- Date: Sat, 7 May 2005 17:35:53 -0000
Hi Grant,
Thanks for pointing out my little mistake. However, it is not this part that
causes the problem (I think) as mod is correctly populated and displayed.
I get a reference to the function back and by adding debug, it can be seen
that it fails on the line that actually calls the function, i.e. theResult =
myFunction(tspName);
Best Regards
Paul
"Grant Schenck" <schenckg@xxxxxxxxxxxxx> wrote in message
news:elBgF70TFHA.3188@xxxxxxxxxxxxxxxxxxxxxxx
> In your "C" sample:
>
> char mod[MAXMODULE];
> ...
> GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE);
>
> You cast mod to a pointer to TCHAR but you declare it a char.
> --
> Grant Schenck
> http://grantschenck.tripod.com
>
>
>
> "Paul Soper" <paul_soper@xxxxxxxxxxx> wrote in message
> news:#XdtTgyTFHA.1600@xxxxxxxxxxxxxxxxxxxxxxx
>> Hi everyone,
>>
>> I know this is not a general programming discussion about accessing DLLs,
>> but I want to disclose
>> my findings because this is TAPI related. I need help to check that I'm
> not
>> missing something stupid in my C code at the bottom of this post.
>>
>> If I use the Delphi code:
>>
>> -------------
>>
>> function TSPI_providerUIIdentify(var lpszUIDLLName : LPWSTR): Longint;
>> stdcall; external 'PSTSP.DLL';
>>
>> procedure TForm1.Button1Click(Sender: TObject);
>>
>> var buffer : LPWSTR;
>>
>> begin
>> GetMem(buffer, MAX_PATH);
>> TSPI_providerUIIdentify(buffer);
>> ShowMessage(' >' + WideCharToString(buffer) + '<');
>> FreeMem(buffer);
>> end;
>>
>> --------------
>>
>> Or, if I use the Visual Basic code:
>>
>> --------------
>>
>> Private Declare Function TSPI_providerUIIdentify Lib "PSTSP.DLL" (ByRef
>> myString As Long) As Long
>>
>> Private Sub Command1_Click()
>> Dim buffer As String
>> Dim answer As Long
>> Dim count As Integer
>>
>> 'Allocate 300 chars in to the String
>> For count = 0 To 299
>> buffer = buffer & "a"
>> Next count
>>
>> answer = TSPI_providerUIIdentify(StrPtr(buffer))
>>
>> MsgBox buffer
>> End Sub
>>
>> --------------
>>
>> all works fine in both cases and I get the correct name back in "buffer".
>>
>> But, if I use the C code (in a console application to keep it simple -
>> Visual C creates masses of code that would complicate the example):
>>
>> --------------
>>
>> #include "stdafx.h"
>> #include <windows.h>
>> #include <iostream.h>
>> #include <stdio.h>
>> #include <conio.h>
>> #include <stdlib.h>
>> #include <malloc.h>
>>
>> #define MAXMODULE 300
>>
>> typedef LONG (WINAPI *cfunc)(LPWSTR lpzUIDLLName);
>>
>> cfunc myFunction;
>> char mod[MAXMODULE];
>> LPWSTR tspName;
>> long theResult;
>>
>> /* very quick and dirty */
>> int main(int argc, char* argv[])
>> {
>> HINSTANCE hLib = LoadLibrary("PSTSP.DLL");
>>
>> if(hLib == NULL) {
>> cout << "Unable to load library!" << endl;
>> getch();
>> return 1;
>> }
>>
>> GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE);
>> cout << "Library loaded: " << mod << endl;
>>
>> myFunction = (cfunc) GetProcAddress((HMODULE)hLib,
>> "TSPI_providerUIIdentify");
>>
>> if(myFunction == NULL) {
>> cout << "Unable to get access to the function!" << endl;
>> FreeLibrary((HMODULE)hLib);
>> getch();
>> return 1;
>> }
>>
>> //malloc 2 bytes per char and 2 for the null
>> tspName = (LPWSTR) malloc((MAX_PATH * 2) + 2);
>>
>> if(tspName == NULL) {
>> cout << "Unable to allocate memory!" << endl;
>> FreeLibrary((HMODULE)hLib);
>> getch();
>> return 1;
>> }
>> else {
>> cout << "Press enter to call the function..." << endl;
>> getch();
>>
>> theResult = myFunction(tspName);
>>
>> cout << tspName << endl;
>>
>> free(tspName);
>> }
>>
>> FreeLibrary((HMODULE)hLib);
>>
>> cout << "Finished... Press enter to close the window." << endl;
>> getch();
>>
>> return 0;
>> }
>>
>> --------------
>>
>> It crashes in a similar way to TAPI when calling this function. Am I
> missing
>> something? (i.e. is my C code OK?). When running this I get the program
> "has
>> encountered a problem and needs to close". The error signature is
>> ModName:
>> kernel32.dll ModVer: 5.1.2600.2180 Offset: 0000 9e4f.
>>
>> I can successfully use the code above to access a functions in the Delphi
>> DLL that print a message to the console, return a long, add two numbers
> and
>> return a result etc. The problem comes when I try and pass a pointer -
>> for
>> example a char*, if I declare my Delphi function signature like this
>> function paultest(instring: PChar) : Longint; stdcall;
>> I can read the value of instring and use it, obviously if I modify it,
> this
>> only modified the local copy (for non Delphi guys, declaring it like the
>> above is pass by value). If I declare it like this
>> function paultest(var instring: PChar) : Longint; stdcall;
>> I cannot read it or write to it without experiencing a C Program crash
> (var
>> indicates pass by reference - basically give me a pointer). I have tried
>> direct assignment and StrCopy etc to write, and reading is simply a case
> of
>> trying to writeln it out.
>>
>> Trying the var/no var scenario with an integer yields the following
> results:
>> 1. c: declare and pass an int, delphi: declare var parameter => crash
>> 2. c: declare and pass an int, delphi: don't declare var => can read the
>> int, but writing affects only the local copy
>> 3. c: declare int and declare int* in external function signature, pass
> &int
>> delphi: declare var parameter => read and write (i.e. modify OK)
>> 4. c: declare int and declare int* in external function signature, pass
> &int
>> delphi: don't declare var => delphi gets the int representation of the
>> pointer (i.e. the address, modification only affects local variable).
>>
>> This is what I would have thought of as "correct behaviour" anyway.
>>
>> All of this indicates to me that there is some problem when trying to
> access
>> any "string" based pointers from Delphi. I think I know need to approach
>> another relevent forum to get the answers I need, as this is no longer in
>> the realm of TAPI.
>>
>> A note to Bram: your function in your code is decalred function
>> TSPI_providerUIIdentify(lpszUIDLLName : LPWSTR) : LONG;
>> stdcall; I don;t understand how this can actually be modifying the
>> lpszUIDLLName. Can you confirm that this actually sets the value external
> to
>> DLL please?
>>
>> Thanks for everyone's help so far. I will report back if I solve this
>> problem.
>>
>> Kind Regards
>>
>> Paul
>>
>>
>>
>
>
.
- References:
- Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- From: Paul Soper
- Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- From: Paul Soper
- Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- From: Grant Schenck
- Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- Prev by Date: VB Sample code for Wave Playback
- Next by Date: Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- Previous by thread: Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- Next by thread: Re: How do I stop a TSP written in Delphi crashing on Add Provider?
- Index(es):