frank
frank

Reputation: 1302

Calling Delphi function in VC Project

I created a function in delphi as below: function CheckResult():integer; stdcall; export;

The compiler is Delphi 64 and the output is CheckFunctions.dll

Then in the VC++ project (VS 2012), I write: extern "C" __declspec(dllimport) int __stdcall CheckResult();

and use it in a function, then I get the compiler error in C++ project:

error LINK2019: unresolved external symbol __imp_CheckResult referenced in function *

How can I do? Thanks

Upvotes: 3

Views: 1430

Answers (3)

moskito-x
moskito-x

Reputation: 11958

With __declspec(dllimport) a __imp__ before the named method is set.

In the generated delphi CheckFunctions.dll there is only a function named CheckResult .
VS C++ 2010 is looking for __imp__CheckResult . Therefore, the linker VS C++ can not find this function.

You have to create a .lib file.
With the program lib.exe this .lib file can be created very easily.
Run LIB.exe from the Visual-studio command-prompt.

LIB creates standard libraries, import libraries, and export files you can use with LINK when building a program.

Overview of LIB

If we have created, with the Visual-studio command-prompt>

C:\VisualStudio100\VC>lib /def:C:\CheckFunctions.def /OUT:C:\CheckFunctions.lib

the CheckFunctions.lib file __imp__CheckResult can be found.

enter image description here

You can test it with following steps
with Delphi5 and Win xp 32 it works.

CheckFunctions.dpr

library CheckFunctions;

uses
  SysUtils,
  Classes;

{$R *.RES}

function CheckResult:integer; stdcall;
begin
   result:=12000;
end;

exports
CheckResult;

begin
end.

Create the def file
CheckFunctions.def

EXPORTS
CheckResult

Create the lib file
Visual Studio command

C:\Programme\VisualStudio100\VC>lib /def:C:\pathToProject\CheckFunctions.def /OUT:C:\pathToProject\CheckFunctions.lib

Copy CheckFunctions.exp and CheckFunctions.lib to
your Visual C++ 2010 Project folder

Visual C++ 2010 CallDll.cpp

#include "stdafx.h"

#define MY_DLL __declspec(dllimport)

extern "C"
{
MY_DLL int CheckResult();
} ;

int _tmain(int argc, _TCHAR* argv[])
{
    int myint = CheckResult();
    printf ("Decimals: %d \n", myint );
    return 0;
}

Update: if you want it with __stdcall

NEW Visual C++ 2010 CallDll.cpp

#include "stdafx.h"

#define MY_DLL __declspec(dllimport)

extern "C"
{
MY_DLL int __stdcall CheckResult();
} ;

int _tmain(int argc, _TCHAR* argv[])
{
    int myint = CheckResult();
    printf ("Decimals: %d \n", myint );
    return 0;
}

change delphi exports

exports
CheckResult name 'CheckResult@0';

Change
CheckFunctions.def

EXPORTS
CheckResult@0
  • Create a new CheckFunctions.lib

That works too.

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595367

Use VC's command-line LIB utility to create a VC-compatible import .lib file for the DLL, then add that file to your VC project.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 612794

You are missing an import library (.lib file) for the DLL. That's why the linker is giving that error message. Unfortunately Delphi won't generate a .lib file which is a bit of a weakness in my view.

You can solve the problem by either:

  1. Linking with LoadLibrary/GetProcAddress.
  2. Generate a suitable .lib file.

Option 2 is easy enough. Create a fake DLL project in Visual Studio. Arrange for it to export the same functions as your Delphi DLL. Implement these functions with empty stubs. Use a .def file rather than __declspec(dllexport) to avoid name decoration of your exports.

It's really obvious really. Make a fake DLL that has an identical interface to the real DLL. The same name, the same functions. The fake DLL needs no implementation because all you are doing is getting the MS tools to make the .lib file that Delphi cannot.

More details here: http://support.microsoft.com/kb/131313


FWIW I believe that the Delphi export modifier is ignored. Use an exports clause instead.

Upvotes: 4

Related Questions