Cannot find entry point of a routine inside a windows 64 dll

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Cannot find entry point of a routine inside a windows 64 dll

Dennis
I am converting my windows 32 program to 64 bit.
It compiled with lazarus without any problem.(fpc 3.0.2)

I also compile the dll that is used, into a 64 bit dll.

However, when I ran the 64 bit program, windows reported 'cannot find
the entry point "the routine name in the dll" (the dll file name)

In the routine of the dll, there is an out parameter of type WideString,

could this be the problem?

If not, what else could be the cause of the problem?

Below is the calling program:
Dennis

---------

const
   ExcelDLLName = 'Excel_xp.dll';//1.90951
Type
    TFileNameString = WideString;//1.90951
    TExcelErrorString = WideString;//1.90952
    TExcelValueString = WideString;//1.90952



    EExcel_OLE=class(Exception);
    EExcel_OLE_Rejected=class(EExcel_OLE);
    EExcel_OLE_Rejected_ToWrite = class(EExcel_OLE_Rejected);

  procedure Excel_Finalize;external ExcelDLLName name 'Finalize';
procedure ResetExcelOLE(out TheError: TExcelErrorString);external
ExcelDLLName;//1.90967

//1.90952 function OpenWorkBook(TheFileName : TFileNameString; out
TheErrorIdx : integer) : integer;external ExcelDLLName;
//1.90952 function OpenWorkSheet(const TheWorkBook : integer; const
TheSheetName : TFileNameString; out TheErrorIdx : integer) :
integer;external ExcelDLLName;

//1.90952  procedure WriteToCell(const TheWorkSheet : integer; const
TheRow, TheCol : integer; TheValue : String);external ExcelDLLName;
//1.90952 function WriteToRange(const TheSheetIndex : integer;TheRow,
StartCol: integer; TheValues: array of variant; IsSkipIfNoChange:
Boolean ) : integer;external ExcelDLLName;//used internally
procedure WriteToExcelRow(const TheSheetIndex: integer; TheRow,
StartCol: integer; TheValues: array of Variant; out TheError:
TExcelErrorString);external ExcelDLLName;//used internally

procedure WriteRow(const TheSheetIndex : integer;TheRow, StartCol:
integer; TheValues: array of variant; var TheError :
TExcelErrorString);external ExcelDLLName;//used internally
//1.90952 function GetCellValue(const TheWorkSheetIndex : integer; const
TheRow, TheCol : integer) : Variant;external ExcelDLLName;


function GetCellVariant(const TheWorkSheetIndex : integer; const TheRow,
TheCol : integer; var TheError : TExcelErrorString) : Variant;external
ExcelDLLName;

function  IsRangeNull(const TheSheetIndex : integer;const TheRow,
StartCol, TheRowCount, TheColCount : integer; var TheError :
TExcelErrorString) : Boolean;external ExcelDLLName;


function GetExcelRange(const TheWorkSheetIndex: integer; const TheRow,
TheCol, TheRowCount, TheColCount: integer; var TheError:
TExcelErrorString): variant; external ExcelDLLName;

function OpenExcelWorkBook(TheFileName: TFileNameString; out TheError:
TExcelErrorString): integer;external ExcelDLLName;
function OpenExcelWorkSheet(const TheWorkBook: integer; const
TheSheetName: TFileNameString; out TheError: TExcelErrorString):
integer;external ExcelDLLName;
procedure WriteToExcelRange(const TheSheetIndex: integer; TheRow,
StartCol: integer; TheValues: Variant; out TheError:
TExcelErrorString);external ExcelDLLName;

procedure ReOpenExcelWorkSheet(TheWorkSheetIndex : integer; out TheError
: TExcelErrorString);external ExcelDLLName;//1.90966
procedure ReOpenExcelWorkBook(TheWorkBookIndex : integer; out TheError :
TExcelErrorString);external ExcelDLLName;//1.90966
procedure SaveAllExcelWorkBooks(out TheError :
TExcelErrorString);external ExcelDLLName;//1.90967
procedure SaveExcelWorkBook(TheBookIndex : integer; out TheError:
TExcelErrorString);external ExcelDLLName;//1.91495

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Free Pascal - General mailing list
Am 13.12.2017 03:04 schrieb "Dennis" <[hidden email]>:
I am converting my windows 32 program to 64 bit.
It compiled with lazarus without any problem.(fpc 3.0.2)

I also compile the dll that is used, into a 64 bit dll.

However, when I ran the 64 bit program, windows reported 'cannot find the entry point "the routine name in the dll" (the dll file name)

In the routine of the dll, there is an out parameter of type WideString,

could this be the problem?

If not, what else could be the cause of the problem?

Considering the code you gave I really wonder how that ever worked... Did you set the calling convention using the $calling directive? Otherwise you need to add it to every function. Also you're on the eager side by using the "name" clause for the external as you can be sure then what name is used. Lastly are you sure that the DLL you're dealing with is a 64-bit library? 

Maybe you should take a look at fpSpreadsheet which allows you to work with Excel files of different versions directly and does not need a library. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Dennis Poon


Sven Barth via fpc-pascal wrote:

> Am 13.12.2017 03:04 schrieb "Dennis" <[hidden email]
> <mailto:[hidden email]>>:
>
>     I am converting my windows 32 program to 64 bit.
>     It compiled with lazarus without any problem.(fpc 3.0.2)
>
>     I also compile the dll that is used, into a 64 bit dll.
>
>     However, when I ran the 64 bit program, windows reported 'cannot
>     find the entry point "the routine name in the dll" (the dll file name)
>
>     In the routine of the dll, there is an out parameter of type
>     WideString,
>
>     could this be the problem?
>
>     If not, what else could be the cause of the problem?
>
>
> Considering the code you gave I really wonder how that ever worked...
> Did you set the calling convention using the $calling directive?
> Otherwise you need to add it to every function. Also you're on the
> eager side by using the "name" clause for the external as you can be
> sure then what name is used. Lastly are you sure that the DLL you're
> dealing with is a 64-bit library?
>
In the original 32 bit program, I wrote the windows 32-bit dll in the
Starter (FREE) edition of Delphi and call (using those codes I showed
you) from my FPC 32 bit program without any problem.
Since there is NO FREE Delphi for 64 bit version, I wrote a windows
64-bit program using FPC 64 bit and then try calling it from my FPC
64-bit program and encountered the "Cannot find entry point of a routine
inside a windows 64 dll" error.

In the 32 bit program, I did not use the $calling directive and did not
use 'name' clause and it worked perfectly.
I could add the name clause in the 64 bit program, but can you teach me
how to use the $calling directive?
Since in the 64 bit version, i will be writing both the dll and the
calling program, what $calling directive should I use?
Do I need to specify it clearly on both the dll and the calling code?

> Maybe you should take a look at fpSpreadsheet which allows you to work
> with Excel files of different versions directly and does not need a
> library.
>
I tried to use the fpSpreadsheet sample program last time. If the 64 bit
dll thing did not work out, I will have to rely on the fpSpreadsheet
thing but my customers are all used to Excel and prefer sticking to it :-(

Thanks for your response.

Dennis
> Regards,
> Sven
>
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Free Pascal - General mailing list
Am 13.12.2017 11:39 schrieb "Dennis Poon" <[hidden email]>:


Sven Barth via fpc-pascal wrote:

Am 13.12.2017 03:04 schrieb "Dennis" <[hidden email] <mailto:[hidden email]>>:

    I am converting my windows 32 program to 64 bit.
    It compiled with lazarus without any problem.(fpc 3.0.2)

    I also compile the dll that is used, into a 64 bit dll.

    However, when I ran the 64 bit program, windows reported 'cannot
    find the entry point "the routine name in the dll" (the dll file name)

    In the routine of the dll, there is an out parameter of type
    WideString,

    could this be the problem?

    If not, what else could be the cause of the problem?


Considering the code you gave I really wonder how that ever worked... Did you set the calling convention using the $calling directive? Otherwise you need to add it to every function. Also you're on the eager side by using the "name" clause for the external as you can be sure then what name is used. Lastly are you sure that the DLL you're dealing with is a 64-bit library?

In the original 32 bit program, I wrote the windows 32-bit dll in the Starter (FREE) edition of Delphi and call (using those codes I showed you) from my FPC 32 bit program without any problem.
Since there is NO FREE Delphi for 64 bit version, I wrote a windows 64-bit program using FPC 64 bit and then try calling it from my FPC 64-bit program and encountered the "Cannot find entry point of a routine inside a windows 64 dll" error.

Just for clarification: is the excel_xp.dll written by you or by a 3rd party? Or are you talking about a different library written by you? Because in the latter case the interfacing choice between your program and *that* library nicht be the culprit. 

In the 32 bit program, I did not use the $calling directive and did not use 'name' clause and it worked perfectly.
I could add the name clause in the 64 bit program, but can you teach me how to use the $calling directive?
Since in the 64 bit version, i will be writing both the dll and the calling program, what $calling directive should I use?
Do I need to specify it clearly on both the dll and the calling code?

Perhaps before we go to this you should first explain a bit more how the structure of your application looks like (regarding libraries), cause currently I'm kinda confused. 


Maybe you should take a look at fpSpreadsheet which allows you to work with Excel files of different versions directly and does not need a library.

I tried to use the fpSpreadsheet sample program last time. If the 64 bit dll thing did not work out, I will have to rely on the fpSpreadsheet thing but my customers are all used to Excel and prefer sticking to it :-(

Are you trying to interact with a love running Excel instance? In that case I agree. However if your trying to modify Excel files that are currently closed then it shouldn't matter whether you use fpSpreadsheet. 

Regards,
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Dennis


Sven Barth via fpc-pascal wrote:

> Am 13.12.2017 11:39 schrieb "Dennis Poon" <[hidden email]
> <mailto:[hidden email]>>:
>
>
>
> Just for clarification: is the excel_xp.dll written by you or by a 3rd
> party? Or are you talking about a different library written by you?
> Because in the latter case the interfacing choice between your program
> and *that* library nicht be the culprit.
>
Let me explain. My program is a 32 bit program that collects real time
stock prices and group the prices by each minute into Open, High, Low,
Close, Volume of that minute. The program needs to add these rows of
open,high,lose,close,volume in real-time to an opened Excel Spreadsheet
(that the end users will write his own VBA formula to manipulate the
rows I add).  To do so, I need to use Microsoft OLE Automation but I
don't know how to do it in Lazarus. But there is a component in Delphi
that uses OLE Automation to update an excel spreadsheet, so I wrote my
own excel_xp.dll in Delphi to use that TExcelApplication component (from
Delphi) which is then called by my 32-bit lazarus program.  Everything
worked in 32-bit.

Since there is no FREE 64-bit Delphi IDE available, before I purchase a
64-Bit delphi, I need to make sure my Lazarus program can compile to 64
bit windows program and can call a 64-bit windows DLL so I use Lazarus
64 bit to write a stub 64-bit windows dll to be called by my 64-bit
Lazarus program. However, on running, it complained "Cannot find entry
point of a routine ", which never happened when everything was 32-bit.

My question is why the exact routine definitions worked in 32-bit but
did not work in 64 bit.

Someone might asked why I did not compile the TExcelApplication directly
in Lazarus to do without the linked dll. I tried, it just won't compile
and the task of translating the huge source files from Delphi to FPC is
too daunting.

Dennis

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Free Pascal - General mailing list
Am 13.12.2017 18:13 schrieb "Dennis" <[hidden email]>:


Sven Barth via fpc-pascal wrote:
Am 13.12.2017 11:39 schrieb "Dennis Poon" <[hidden email] <mailto:[hidden email]>>:



Just for clarification: is the excel_xp.dll written by you or by a 3rd party? Or are you talking about a different library written by you? Because in the latter case the interfacing choice between your program and *that* library nicht be the culprit.

Let me explain. My program is a 32 bit program that collects real time stock prices and group the prices by each minute into Open, High, Low, Close, Volume of that minute. The program needs to add these rows of open,high,lose,close,volume in real-time to an opened Excel Spreadsheet (that the end users will write his own VBA formula to manipulate the rows I add).  To do so, I need to use Microsoft OLE Automation but I don't know how to do it in Lazarus. But there is a component in Delphi that uses OLE Automation to update an excel spreadsheet, so I wrote my own excel_xp.dll in Delphi to use that TExcelApplication component (from Delphi) which is then called by my 32-bit lazarus program.  Everything worked in 32-bit.

Since there is no FREE 64-bit Delphi IDE available, before I purchase a 64-Bit delphi, I need to make sure my Lazarus program can compile to 64 bit windows program and can call a 64-bit windows DLL so I use Lazarus 64 bit to write a stub 64-bit windows dll to be called by my 64-bit Lazarus program. However, on running, it complained "Cannot find entry point of a routine ", which never happened when everything was 32-bit.

My question is why the exact routine definitions worked in 32-bit but did not work in 64 bit.

Okay, that explains things a bit more. 

May I ask you to provide a small example consisting of program and library (source only) that works in 32-bit, but fails in 64-bit? Try way I can check myself what is going on as I have a Delphi starter on my 64-bit Windows as well. Though it will be the weekend till I'll have the time to look at it.

Someone might asked why I did not compile the TExcelApplication directly in Lazarus to do without the linked dll. I tried, it just won't compile and the task of translating the huge source files from Delphi to FPC is too daunting.

 What kind of errors did you face? 

Regards, 
Sven

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Dennis
>
> Okay, that explains things a bit more.
>
> May I ask you to provide a small example consisting of program and
> library (source only) that works in 32-bit, but fails in 64-bit? Try
> way I can check myself what is going on as I have a Delphi starter on
> my 64-bit Windows as well. Though it will be the weekend till I'll
> have the time to look at it.

Sven,

Attached is a zipped file containing the Caller program and Callee dll.
Both Compiled ok in windows 32 but when running Caller.exe, it reported
the error.

Thanks a lot.

Dennis

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

TESTDLL.zip (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Free Pascal - General mailing list
On 15.12.2017 16:10, Dennis wrote:

>>
>> Okay, that explains things a bit more.
>>
>> May I ask you to provide a small example consisting of program and
>> library (source only) that works in 32-bit, but fails in 64-bit? Try
>> way I can check myself what is going on as I have a Delphi starter on
>> my 64-bit Windows as well. Though it will be the weekend till I'll
>> have the time to look at it.
>
> Sven,
>
> Attached is a zipped file containing the Caller program and Callee dll.
> Both Compiled ok in windows 32 but when running Caller.exe, it reported
> the error.
>
> Thanks a lot.

There were two adjustments I had to do to make it work correctly:

- add {$mode objfpc} to Caller.lpr as I was compiling from the commandline
- adjust the casing of ReOpenExcelWorkBook so that it matched the one
from ReopenExcelWorkBook (these are case sensitive!)

With these changes it worked without problem on win64.

That said you might want to apply the following two points to your
library interface:
- export/import functions/procedures using explicit names (extending
"external LibName" to "external LibName name 'ProcName'" for each
routine to import and adding "name 'ProcName'" for each routine in the
exports section) to be sure that no name mangling interferes here
- add an explicit calling convention to each routine for import and
export (you could use "register", the default calling convention since
Delphi and FPC *should* be compatible here, but "stdcall" would be my
suggestion to be on the save side)

Additionally you can check for any discrepancies using the Dependency
Walker ( http://www.dependencywalker.com/ ). Just open the executable
while the library is located in the same directory and you can see which
routines mismatch.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Cannot find entry point of a routine inside a windows 64 dll

Dennis


Sven Barth via fpc-pascal wrote:

> On 15.12.2017 16:10, Dennis wrote:
>>> Okay, that explains things a bit more.
>>>
>>> May I ask you to provide a small example consisting of program and
>>> library (source only) that works in 32-bit, but fails in 64-bit? Try
>>> way I can check myself what is going on as I have a Delphi starter on
>>> my 64-bit Windows as well. Though it will be the weekend till I'll
>>> have the time to look at it.
>> Sven,
>>
>> Attached is a zipped file containing the Caller program and Callee dll.
>> Both Compiled ok in windows 32 but when running Caller.exe, it reported
>> the error.
>>
>> Thanks a lot.
> There were two adjustments I had to do to make it work correctly:
>
> - add {$mode objfpc} to Caller.lpr as I was compiling from the commandline
> - adjust the casing of ReOpenExcelWorkBook so that it matched the one
> from ReopenExcelWorkBook (these are case sensitive!)
>
> With these changes it worked without problem on win64.
>
> That said you might want to apply the following two points to your
> library interface:
> - export/import functions/procedures using explicit names (extending
> "external LibName" to "external LibName name 'ProcName'" for each
> routine to import and adding "name 'ProcName'" for each routine in the
> exports section) to be sure that no name mangling interferes here
> - add an explicit calling convention to each routine for import and
> export (you could use "register", the default calling convention since
> Delphi and FPC *should* be compatible here, but "stdcall" would be my
> suggestion to be on the save side)
>
> Additionally you can check for any discrepancies using the Dependency
> Walker ( http://www.dependencywalker.com/ ). Just open the executable
> while the library is located in the same directory and you can see which
> routines mismatch.
>
> Regards,
> Sven


Thank you so much!!!

Dennis
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal