2013-04-17 3 views
4

Мне нужно создать динамическую библиотеку DLL на C++, чтобы заменить старую библиотеку DLL, написанную на Fortran, без изменения хост-приложения (поэтому функции и параметры должны оставаться одна и та же).Как создать динамическую библиотеку DLL в C++, чтобы заменить устаревшую библиотеку Fortran DLL

У меня есть полная спецификация всех функций Fortran в этой библиотеке, но какие инструменты (компилятор) мне нужно использовать, и каков способ кодирования DLL в этой ситуации (stdcall, cdecl, dllexport и т. Д.). Я не говорю много для меня, я никогда не создавал DLL раньше).

Это пример Fortran объявление функции в унаследованной DLL:

SUBROUTINE SetBoundaries(MaxFlow, MinFlow) 
cDEC$ ATTRIBUTES DLLEXPORT :: SetBoundaries 
cDEC$ ATTRIBUTES ALIAS: "SetBoundaries" :: SetBoundaries 

REAL MaxFlow 
REAL MinFlow 

Я попытался собрать VC2008 DLL, но получил сообщение об ошибке:

Unhandled error in 'InitAllPublicVars' Run-time error 453: Can't find DLL entry point DLLVersion in SomeLib.DLL

Источник этой DLL (определение функции с именем DLLVersion не help):

void __stdcall SetBoundaries(float *min , float *max) { 
} 

Является DLLVersion некоторой специальной процедурой DLL или просто отсутствует в моя документация, и я должен создать такую ​​функцию?

Я не знаю никаких подробностей о первоначальном Fortran DLL источнике/процессе компиляции, но есть некоторые извлекаемая информация:

General Some options Imports

+0

Какой компилятор Fortran использовался для сборки библиотеки DLL? Какие параметры командной строки были использованы с этим компилятором? Какой компилятор C++ вы используете? – IanH

+0

C++ - любой, Fortran - у меня нет информации. Вопрос обновлен с некоторыми извлеченными деталями. –

ответ

2

Я нашел решение. Функции DLL должны быть объявлены следующим образом:

extern "C" void __declspec(dllexport) SetBoundaries(int min , int max) { 

} 

Обратите внимание, что параметры не являются указателями. Я зарегистрировал вызовы функций, а DLL получает действительные числа из хост-приложения, если вместо оригинальной библиотеки Fortran. Скомпилирован с Visual Studio 2008.

+0

Ницца! Мне нравятся такие проекты, где вы можете легко отбросить что-то новое в нечто старое через определенный интерфейс.Ваша Fortran DLL, которая знает, что, может быть, теперь заменена вашей DLL, которая говорит о связке ядер GPU через CUDA или что-то еще. Престижность! –

4

Библиотека времени выполнения делает Фортран DLL выглядеть, как он был построен с компиляторы Compaq или Digital Fortran. По умолчанию эти компиляторы использовали соглашение о вызове stdcall. Для вашего конкретного примера два аргумента (параметры на стороне C) эквивалентны float *, подпрограммы эквивалентны функциям void. Вам нужно будет использовать компилятор C++, поддерживающий stdcall. Как вы назначаете, что функция экспортируется в DLL, зависит от вашего компилятора C++ или личных предпочтений, но типичное ключевое слово dllexport.

С точки зрения управления изменениями было бы гораздо проще написать замену DLL в Fortran и использовать что-то вроде компилятора Intel Fortran, который, будучи потомком компилятора CVF, имеет соответствующую унаследованную поддержку. Изменения в исходном коде DLL могут быть сделаны прогрессивным образом.

+0

Спасибо, я проверю это. Итак, вы имеете в виду, что если я использую C++-компилятор с поддержкой stdcall и определяю функцию типа 'void __stdcall SetBoundaries (float *, float *)', то скомпилированная DLL должна работать с оригинальным приложением? (на уровне вызова функции, конечно, не бизнес-логики). Любые другие объявления, требуемые в файле C/C++? нужна ли основная функция? –

+0

Вопрос обновлен, у меня есть ошибка «Не удается найти DLL-точку DLL-записи» –

Смежные вопросы