Вызов Delphi DLL из Visual C++
Во-первых, Вам необходимо объявить все экспортируемые в Delphi DLL функции с ключевыми словами export; stdcall;
Во-вторых, файл заголовка VC++ должен объявить все функции как тип __declspec(dllexport) __stdcall (применяйте двойное подчеркивание в секции объявления прототипа функции extern "C" { ... }. (вместо этого можно также использовать __declspec(dllimport)...). Для примера:
extern "C" {В-третьих, в VC++ компилятор настраивается на "украшающее" имена функций __stcall, так что Ваша Delphi DLL соответственно должна экспортировать эти функции. Для этого необходимо модифицировать файл Delphi 2.0 .DPR для Вашего DLL, модифицируя имена всех функций, прописанных в разделе экспорта. Для примера, если Вы экспортируете функцию function plusone (intval : Integer), Вам необходимо включить следующую строку в раздел экспорта .DPR-файла:
Число, следующее за символом @, является общей длиной в байтах всех функциональных аргументов. Самый простой путь для обнаружения неправильных значений - попытаться слинковать Вашу VC++ программу и посмотреть на наличие возможной ошибки компоновщика "unresolved external".
И, наконец, Вы можете легко создать библиотеку импорта, используя утилиту LIB из поставки VC++. Для этого необходимо вручную (!!) создать .DEF-файл для Вашей DLL с секцией экспорта, перечисляющей имена и/или порядковые номера всех экспортируемых DLL функций. Формат .DEF-файла очень прост:
library MYLIB
description 'Моя собственная DLL'
exports
Затем запускаете LIB из командной строки DOS/Win95, и в качестве параметра подставляете имя .DEF-файла. Например, LIB /DEF:MYDLL.DEF. Наконец, через диалог Build|Settings|Linker Вы информируете VC++ о полученном .LIB-файле.
Вот пример кода:
*******MYDLLMU.PAS unit MyDLLMU;
interface
function plusone(val : Integer) : Integer; export; stdcall;
procedure ChangeString(AString : PChar); export; stdcall;
implementation
uses
function plusone(val : Integer) : Integer;
begin
procedure ChangeString(AString : PChar);
begin
end.
***********MYDLL.DPR library mydll;
{ Существенное замечание об управлении памятью в DLL: Если DLL экспортирует функции со
uses
exports
begin
end.
*************** MYDLL.DEF
; -----------------------------------------------------------------
; Имя файла: MYDLL.DEF
; -----------------------------------------------------------------
LIBRARY MYDLL
DESCRIPTION 'Тестовая Delphi DLL, статическая загрузка в VC++ приложение'
EXPORTS
************** DLLTSTADlg.H // DLLTSTADlg.h : заголовочный файл
//
#define USELIB
#ifdef USELIB
extern "C" {
#endif //USELIB
/////////////////////////////////////////////////////////////////////////////
// Диалог CDLLTSTADlg
class CDLLTSTADlg : public CDialog
{
// Создание public:
// Данные диалога
// Реализация
protected:
#ifndef USELIB
************ DLLTSTADlg.CPP // DLLTSTADlg.cpp : файл реализации
//
#include "stdafx.h"
#include "DLLTSTA.h"
#include "DLLTSTADlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CDLLTSTAApp theApp;
/////////////////////////////////////////////////////////////////////////////
// Диалог CDLLTSTADlg
CDLLTSTADlg::CDLLTSTADlg(CWnd* pParent /*=NULL*/)
#ifndef USELIB
}
CDLLTSTADlg::~CDLLTSTADlg()
{
#ifndef USELIB
}
void CDLLTSTADlg::DoDataExchange(CDataExchange* pDX)
{
BEGIN_MESSAGE_MAP(CDLLTSTADlg, CDialog)
/////////////////////////////////////////////////////////////////////////////
// Дескрипторы сообщений CDLLTSTADlg
BOOL CDLLTSTADlg::OnInitDialog()
{
// Если Вы добавляете в диалог кнопку минимизации, для создания иконки Вам
// необходим код, приведенный ниже. Для MFC-приложений используйте
// document/view model для автоматического создания скелета кода.
void CDLLTSTADlg::OnPaint()
{
// Система вызывает данный код для получения курсора, выводимого если
// пользователь пытается перетащить свернутое окно.
HCURSOR CDLLTSTADlg::OnQueryDragIcon()
{
void CDLLTSTADlg::OnBtnplusoneClick()
{
void CDLLTSTADlg::OnBtndostringClick()
{
}