Сбой, когда программа C ++ вызывает функцию DLL Delphi - PullRequest
1 голос
/ 12 декабря 2010

У меня есть абстрактный класс в программе на C ++, который выглядит как

class Interface {
    virtual void blah() = 0;
    virtual int  asdf() = 0;
};

, и эта программа на C ++ позволяет загружать библиотеки DLL с помощью LoadLibrary.Когда вы загружаете DLL, она вызывает функцию в DLL, которая называется Setup с GetProcAddress, передавая указатель на подкласс Interface в качестве параметра.

У меня есть DLL-библиотека Delphi, имитирующая этот класс, и открывающая функцию установки следующим образом:

type 
Interface = class abstract
    procedure blah(); virtual; abstract;
    function asdf() : Integer; virtual; abstract;
end;

function Setup(I : Interface) : Integer; export; cdecl;
begin
    Result := 0;
end

exports Setup;

Но когда программа вызывает функцию, она падает.Если я изменю функцию Setup на эту:

function Setup(I : Pointer) : Integer; export; cdecl;

Она работает нормально и не вылетает, но, конечно, я не могу просто так ее оставить, мне нужно иметь возможность использовать класс.Может кто-нибудь сказать мне, что я делаю не так?

Ответы [ 3 ]

2 голосов
/ 12 декабря 2010

Я не знаю о C ++, но интерфейсы Delphi автоматически подсчитывают ссылки (через IUnknown).Похоже, ваш интерфейс уже разрушен к тому времени, когда вы пытаетесь его использовать.

Редактировать: Извините, я был смущен: вы не используете интерфейсы.

Delphi и C ++классы не совместимы, поэтому я не думаю, что это сработает.Вам придется изменить класс на интерфейс COM или запись указателей функций.Боюсь, если у вас нет контроля над C ++, вам не повезло.

1 голос
/ 12 декабря 2010

Если ваш код C ++ действительно такой, как вы говорите, вам нужно определить, какое соглашение о вызовах он использует. Это определенно использует соглашение о вызовах C? С чем он скомпилирован и какие флаги для соглашения о вызовах?

Ваш Interface класс должен также включать соглашение о вызовах, что-то вроде:

Interface = class abstract
  procedure blah(); cdecl; virtual; abstract;
  function asdf() : Integer; cdecl; virtual; abstract;
end;

Если соглашение о вызовах, используемое в C ++, похоже на fastcall MSVC, в Delphi нет прямого эквивалента. В этом случае вы можете написать прокси-DLL в MSVC, которая преобразует интерфейс из FastCall MSVC в cdecl или аналогичный.

0 голосов
/ 01 января 2011

Вы могли видеть http://rvelthuis.de/articles/articles-cppobjs.html

Но да, использование C ++ в Delphi - дело непростое ... и не подходящее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...