Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сборка DLL C++ Builder 6.0

16K
19 апреля 2006 года
rsn
5 / / 19.04.2006
Необходимо собрать DLL-библиотеку, функции которой будут использоваться, к примеру, в VFP.

Тестовый пример.
Заголовочный файл:
 
Код:
#ifndef _Unit1_h
#define _Unit1_h
#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else

#define DLL_EI __declspec(dllimport)
#endif
void DLL_EI __stdcall test();
#endif

Файл реализации:
 
Код:
#include <vcl.h>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) {
    return 1;
}
#include "Unit1.h"
void __stdcall test() {
    ;
}

Вызов функции из VFP:
 
Код:
declare test in "c:\projects\test\project1.dll"
=test()

Не может найти функцию test (can't find entry point test in DLL).

Смотрим структуру собранной DLL, к примеру, через утилиту impdef:
Цитата:
impdef project1.def project1.dll


Содержимое project1.def:

Цитата:
LIBRARY PROJECT1.DLL

EXPORTS
@test$qv @1 ; test()
___CPPdebugHook @2 ; ___CPPdebugHook



Читаю статью, начинаю играть опциями компилятора и линковщика.

Изменение опций: calling convention, don't mangle code modifiers - ничего дает, функция все равно с "искаженным" названием.

Уже отчаялся, подскажите, что делаю не так? Заранее благодарен.

324
19 апреля 2006 года
AndreySar
532 / / 01.08.2004
Цитата:
Originally posted by rsn
Необходимо собрать DLL-библиотеку, функции которой будут использоваться, к примеру, в VFP.

Тестовый пример.
Заголовочный файл:
 
Код:
#ifndef _Unit1_h
#define _Unit1_h
#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else

#define DLL_EI __declspec(dllimport)
#endif
void DLL_EI __stdcall test();
#endif

Файл реализации:
 
Код:
#include <vcl.h>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) {
    return 1;
}
#include "Unit1.h"
void __stdcall test() {
    ;
}

Вызов функции из VFP:
 
Код:
declare test in "c:\projects\test\project1.dll"
=test()

Не может найти функцию test (can't find entry point test in DLL).

Смотрим структуру собранной DLL, к примеру, через утилиту impdef:

Содержимое project1.def:


Читаю статью, начинаю играть опциями компилятора и линковщика.

Изменение опций: calling convention, don't mangle code modifiers - ничего дает, функции все равно с "искаженными" названиями функция.

Уже отчаялся, подскажите, что делаю не так? Заранее благодарен.



Укажи, что твоя функция export

16K
19 апреля 2006 года
rsn
5 / / 19.04.2006
Цитата:
Originally posted by AndreySar
Укажи, что твоя функция export


Так в заголовочном ведь присутствует директива __declspec(dllexport), функция экспортируется, но с "искаженным" именем. Или я не о том? :-)

Проблема именно в доступе к функции из не C-подобного языка. Динамическое связывание DLL-библиотеки на C++ в том же Builder-е работает нормально:

Код:
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#pragma argsused
int main(int argc, char* argv[]) {
    void (*test)();
    HINSTANCE dllp = LoadLibrary("project1.dll");
    if (dllp) {
        test = (void(*) ())
        GetProcAddress(dllp, "_test");
        if (test)
            test();
        else
            printf("test not found.");
    }
    FreeLibrary(dllp);
    return 0;
}
324
19 апреля 2006 года
AndreySar
532 / / 01.08.2004
Цитата:
Originally posted by rsn
Так в заголовочном ведь присутствует директива __declspec(dllexport), функция экспортируется, но с "искаженным" именем. Или я не о том? :-)

Проблема именно в доступе к функции из не C-подобного языка. Динамическое связывание DLL-библиотеки на C++ в том же Builder-е работает нормально:
Код:
#include <vcl.h>
#pragma hdrstop
#pragma argsused
int main(int argc, char* argv[]) {
    void (*test)();
    HINSTANCE dllp = LoadLibrary("project1.dll");
    if (dllp) {
        test = (void(*) ())
        GetProcAddress(dllp, "_test");
        if (test)
            test();
        else
            printf("test not found.");
    }
    FreeLibrary(dllp);
    return 0;
}



В DLL могут входить как экспортируемые функции, так и внутренние. В данном случае у тебя тест объявлена как внутренняя. Укажи явно что она является export

16K
19 апреля 2006 года
rsn
5 / / 19.04.2006
Цитата:
Originally posted by AndreySar
В DLL могут входить как экспортируемые функции, так и внутренние. В данном случае у тебя тест объявлена как внутренняя. Укажи явно что она является export


Гм... разницу между внутренними функциями DLL и экспортируемыми понимаю, как и то, что спецификаторы _export и __declspec(dllexport) идентичны. Второй вариант - мой.

Функция test объявлена как экспортируемая (см. внимательно заголовочный файл), после раскрытия маркоса DLL_EI будет:

 
Код:
void _export __declspec(dllexport) __stdcall test();
406
19 апреля 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by rsn
Гм... разницу между внутренними функциями DLL и экспортируемыми понимаю, как и то, что спецификаторы _export и __declspec(dllexport) идентичны. Второй вариант - мой.

Функция test объявлена как экспортируемая (см. внимательно заголовочный файл), после раскрытия маркоса DLL_EI будет:
 
Код:
void _export __declspec(dllexport) __stdcall test();


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

 
Код:
extern "C" void _export __declspec(dllexport) __stdcall test();


не знаю действует ли такое билдере
14K
20 апреля 2006 года
viva
27 / / 07.04.2006
Цитата:
Originally posted by vitaly2003s
У тебя проблема скорее всего с декорацией имен,я бы в VisualStudio C++ зделал бы так:
 
Код:
extern "C" void _export __declspec(dllexport) __stdcall test();


не знаю действует ли такое билдере



Именно так надо писать и в C++Builder.

Вот только в VFP, скорее всего, при объявлении надо поставить подчерк перед test, то есть

 
Код:
declare _test in "c:\projects\test\project1.dll" as test
=test()
16K
20 апреля 2006 года
rsn
5 / / 19.04.2006
 
Код:
extern "C" void _export __declspec(dllexport) __stdcall test();

О, помогло. :-)

Два ньюанса:
1. Таки директивы _export и __declspec(dllexport), насколько понял, идентичны. Итого, сработал вариант:
 
Код:
extern "C" void __declspec(dllexport) __stdcall test();
2. При такой сборке символ "_" не добавляется, то есть повсеместно DLL экспортирует функции с полным названием без добавлений.

Благодарю, господа. :-)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог