Экспорт из DLL
Участников: 4
Страница 1 из 1
Экспорт из DLL
Я этот вопрос задавал на англоязычном форуме, но толкового ответа так и не было . Проблема вот в чем: хочу на FB написать, к примеру, расширенную хранимую процедуру для SQL Server 2000 . Понятно, что ее имя должно быть экспортировано. На VC++/MASM в DLL экспорт идет нормально - по обычным именам , а вот FB добавляет к имени кол-во параметров . Я понимаю, что это stdcall, но VC++/MASM обходятся без этого, а в FB - такая напряга. ВОПРОС:
Как сделать экспортные имена нормальными, без указания кол-ва параметров?
В конце концов, это ж не .LIB-файл, а DLL...
Как сделать экспортные имена нормальными, без указания кол-ва параметров?
В конце концов, это ж не .LIB-файл, а DLL...
vbman- Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 42
Откуда : Украина, Кировоград
Re: Экспорт из DLL
если я правильно понял, то FB добавляет к имени функции чета типа func@16 , типа кол-во байт параметров, была у мня та же проблема, решал я ее поначалу добавлением в вызывающую функцию ету собаку с цифрами, как ни странно, но это работало (вызывалась библиотека из Си-шки), но решил эту проблему помоему алиасингом при экспорте (непомню точно):
помоему даже stdcall не трогал...
- Код:
declare fMyFunc alias "fMyFunc" ()
function fMyFunc() as integer export
function=0
end function
помоему даже stdcall не трогал...
Re: Экспорт из DLL
да нет проблем! разработчики FreeBasic, хорошо постарались! есть несколько типов деклараций функций и процедур.
stdcall- STANDART CALL, функция сама очищает стек
cdecl- C DECLARATION, очистка стека ложится на программиста, FreeBasic при компиляции определяет сколько параметров передали той или иной функции и в процессе компиляции, после вызова функции, добавляет стековый регистр сам.
функции типа cdecl, могут иметь не фиксированное число параметров.
pascal- декларация типа паскаль, параметры функций заносятся в стек в обратном порядке, может пригодиться при потключении delphi библиотек продекларированых как pascal.
fastcall, что такое, толком не знаю, и во FreeBasic не поддерживается.
а теперь о dll, чтобы во FreeBasic в dll, не записывалось число параметров типа:
@4 @16 @ 64, можно продекларировать функцию как
cdecl, но тогда в языках высокого уровня, обязательно в декларации нужно прописать cdecl. если вы потключаете к ассемблеру, придется выравнивать стек, так как функции типа cdecl, при их запуске, не сохраняют стековый регистр, соответственно при завершении функций не восстанавливают. они только перед запуском, забирают в стек параметры, а вот после выполнения, тут ушь ваша задача определить по количеству параметров, сколько надо прибавить к стековому регистру, чтоб его выровнять.
ну а теперь пример:
код dll:
declare function testfunc cdecl alias "TestFunc"_
(byval num1 as integer,byval num2 as integer) as integer
function testfunc cdecl (byval num1 as integer,byval num2 as integer) as integer export
function=num1 + num2
end function
компилируем: fbc -dll testfunc.dll
код примера:
declare function testfunc cdecl lib "testfunc" alias "TestFunc"_
(byval num1 as integer,byval num2 as integer) as integer
print testfunc(15, 5)
я недавно столкнулся с библиотекой написанной на delphi, функции были продекларированы как stdcall, и FreeBasic, в упор отказывался видеть функции из этой dll. оказалось, что FreeBasic их не видит из-за вот этих отсутствующих @4 @16. пришлось вызывать стандартным winapi таким путем:
код:
declare function LoadLibrary lib "kernel32" alias "LoadLibraryA" (byval as zstring ptr) as integer
declare function GetProcAddress lib "kernel32" alias "GetProcAddress"_
(byval as integer, byval as zstring ptr) as any ptr
dim handleLib as integer = loadlibrary("mylib.dll") 'получаем идентификатор загруженной библиотеки
dim initialize as function() as integer = getprocaddress(handleLib,"initialize") 'получаем адрес функции в библиотеке
print initialize() 'смотрим на экран, что там она вернула
так что, если у вас не получается справиться с какой-нибудь dll средствами FreeBasic, не бросайте, попробуйте средствами winApi. в чем различие функций stdcall со всякими @8 @32, от функций stdcall beз них, хрен знает, но я так думаю, что внутри функций все одинаково. видимо стандарты borland, microsoft и т.д отличаются и введены для совместимости.
а вообще, кто умеет писать хорошо по английски, пожалуйста, напишите разработчикам FreeBasic, чтоб можно было делать функции stdcall средствами FreeBasic без @4 @8. так потключение левых библиотек будет более гибким.
stdcall- STANDART CALL, функция сама очищает стек
cdecl- C DECLARATION, очистка стека ложится на программиста, FreeBasic при компиляции определяет сколько параметров передали той или иной функции и в процессе компиляции, после вызова функции, добавляет стековый регистр сам.
функции типа cdecl, могут иметь не фиксированное число параметров.
pascal- декларация типа паскаль, параметры функций заносятся в стек в обратном порядке, может пригодиться при потключении delphi библиотек продекларированых как pascal.
fastcall, что такое, толком не знаю, и во FreeBasic не поддерживается.
а теперь о dll, чтобы во FreeBasic в dll, не записывалось число параметров типа:
@4 @16 @ 64, можно продекларировать функцию как
cdecl, но тогда в языках высокого уровня, обязательно в декларации нужно прописать cdecl. если вы потключаете к ассемблеру, придется выравнивать стек, так как функции типа cdecl, при их запуске, не сохраняют стековый регистр, соответственно при завершении функций не восстанавливают. они только перед запуском, забирают в стек параметры, а вот после выполнения, тут ушь ваша задача определить по количеству параметров, сколько надо прибавить к стековому регистру, чтоб его выровнять.
ну а теперь пример:
код dll:
declare function testfunc cdecl alias "TestFunc"_
(byval num1 as integer,byval num2 as integer) as integer
function testfunc cdecl (byval num1 as integer,byval num2 as integer) as integer export
function=num1 + num2
end function
компилируем: fbc -dll testfunc.dll
код примера:
declare function testfunc cdecl lib "testfunc" alias "TestFunc"_
(byval num1 as integer,byval num2 as integer) as integer
print testfunc(15, 5)
я недавно столкнулся с библиотекой написанной на delphi, функции были продекларированы как stdcall, и FreeBasic, в упор отказывался видеть функции из этой dll. оказалось, что FreeBasic их не видит из-за вот этих отсутствующих @4 @16. пришлось вызывать стандартным winapi таким путем:
код:
declare function LoadLibrary lib "kernel32" alias "LoadLibraryA" (byval as zstring ptr) as integer
declare function GetProcAddress lib "kernel32" alias "GetProcAddress"_
(byval as integer, byval as zstring ptr) as any ptr
dim handleLib as integer = loadlibrary("mylib.dll") 'получаем идентификатор загруженной библиотеки
dim initialize as function() as integer = getprocaddress(handleLib,"initialize") 'получаем адрес функции в библиотеке
print initialize() 'смотрим на экран, что там она вернула
так что, если у вас не получается справиться с какой-нибудь dll средствами FreeBasic, не бросайте, попробуйте средствами winApi. в чем различие функций stdcall со всякими @8 @32, от функций stdcall beз них, хрен знает, но я так думаю, что внутри функций все одинаково. видимо стандарты borland, microsoft и т.д отличаются и введены для совместимости.
а вообще, кто умеет писать хорошо по английски, пожалуйста, напишите разработчикам FreeBasic, чтоб можно было делать функции stdcall средствами FreeBasic без @4 @8. так потключение левых библиотек будет более гибким.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: Экспорт из DLL
electrik пишет:
я недавно столкнулся с библиотекой написанной на delphi, функции были продекларированы как stdcall, и FreeBasic, в упор отказывался видеть функции из этой dll. оказалось, что FreeBasic их не видит из-за вот этих отсутствующих @4 @16.
а вообще, кто умеет писать хорошо по английски, пожалуйста, напишите разработчикам FreeBasic, чтоб можно было делать функции stdcall средствами FreeBasic без @4 @8. так потключение левых библиотек будет более гибким.
Я переделывал прогу с VB на FB, переделка как раз заключалась в том, чтобы убрать ненужные размеры параметров из объявлений.... было в оригинале alias "MyFunc@24", пришлось везде убирать до состояния alias "MyFunc" и тогда заработало из FB нормально.
Re: Экспорт из DLL
DoReMi писал:
Я переделывал прогу с VB на FB, переделка как раз заключалась в том, чтобы убрать ненужные размеры параметров из объявлений.... было в оригинале alias "MyFunc@24",
пришлось везде убирать до состояния alias "MyFunc" и тогда заработало из FB нормально.
я правта не понял к чему ты это говориш, но в библиотеках в которых есть информация о размерах параметров, сделанных на FreeBasic или в winapi, их как раз в алиасах указывать не нужно. цель убрать из dll эти не нужные параметры. тоесть, я так понял, чтоб к vb потключить fb библиотеку, и если функции stdcall, в vb надо указывать эти параметры.
Я переделывал прогу с VB на FB, переделка как раз заключалась в том, чтобы убрать ненужные размеры параметров из объявлений.... было в оригинале alias "MyFunc@24",
пришлось везде убирать до состояния alias "MyFunc" и тогда заработало из FB нормально.
я правта не понял к чему ты это говориш, но в библиотеках в которых есть информация о размерах параметров, сделанных на FreeBasic или в winapi, их как раз в алиасах указывать не нужно. цель убрать из dll эти не нужные параметры. тоесть, я так понял, чтоб к vb потключить fb библиотеку, и если функции stdcall, в vb надо указывать эти параметры.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: Экспорт из DLL
я остался в дураках. разработчики FreeBasic, супер постарались, а я знал про некоторые функции и их избегал а пользовался декларациями так:
declare function initialize lib "my.dll" alias "initialize"()
вот таким методом, функции из delphi библиотеки, я не завел, так как у них нет параметров типа @4 @16. пришлось воспользоватся winApi.
а ведь все проще, я не правильно думал, что так не сработает, и в упор не пользовался функциями типа:
dyLibLoad
dyLibSymbol
а теберь окончательный и я так думаю правильный вариант, только для многоплатформенных приложений:
код:
dim handleLib as any ptr = dylibload("my.dll")
dim initialize as function() as integer = dylibsymbol(handlelib,"initialize")
этот метод хорошо работает, но бинарник немного больше. так что если вы пишете только под винду, и хотите выпендрится мелким бинарником, пользуйтесь WinApi функциями типа:
LoadLibrary
GetProcAddress
чем отличается объявление функций из dll через "declare"?
если мы объявляем функцию через "declare" потом указываем к примеру
lib "ny.dll"
эти функции с именем библиотеки прописываются в таблице "import" нашей программы. это дает просмотреть всякими ресурс редакторами, какие библиотеки программа использует, и какие функции из них вызывает.
если использовать метод типа
loadlibrary(kernell32.dll")
ну тут, уже надо отлавливать дебагером или дизассемблировать. тоесть в таблице импорта нашей библиотеки нет.
declare function initialize lib "my.dll" alias "initialize"()
вот таким методом, функции из delphi библиотеки, я не завел, так как у них нет параметров типа @4 @16. пришлось воспользоватся winApi.
а ведь все проще, я не правильно думал, что так не сработает, и в упор не пользовался функциями типа:
dyLibLoad
dyLibSymbol
а теберь окончательный и я так думаю правильный вариант, только для многоплатформенных приложений:
код:
dim handleLib as any ptr = dylibload("my.dll")
dim initialize as function() as integer = dylibsymbol(handlelib,"initialize")
этот метод хорошо работает, но бинарник немного больше. так что если вы пишете только под винду, и хотите выпендрится мелким бинарником, пользуйтесь WinApi функциями типа:
LoadLibrary
GetProcAddress
чем отличается объявление функций из dll через "declare"?
если мы объявляем функцию через "declare" потом указываем к примеру
lib "ny.dll"
эти функции с именем библиотеки прописываются в таблице "import" нашей программы. это дает просмотреть всякими ресурс редакторами, какие библиотеки программа использует, и какие функции из них вызывает.
если использовать метод типа
loadlibrary(kernell32.dll")
ну тут, уже надо отлавливать дебагером или дизассемблировать. тоесть в таблице импорта нашей библиотеки нет.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Вы не поняли
в таблице экспорта ДЛЛ-ки четко прописано (если у нас в DLL есть функция Msg(byval m as zstring ptr)):
MSG@4
А надо бы, по идее, чтобы было просто Msg
отсюда проблемы для использования таких библиотек в других, не ФриБейсиковых программах. Сам ФриБейсик понимает их нормально - безо всяких префиксов.
Выход есть, но не спасает:
дописать конвенцию cdecl в заголовке функции и алиасное имя и тогда мы получим нормальное имя (Msg), но тогда, к примеру, при вызове из VB функция отрабатывает нормально, но возникает другая ошибка: Bad dll calling convention, т. к. VB понимает stdcall. Выравнивание стека в самой функции не помогает... Вот так вот..
А хотелось бы, чтобы как в МАСМе - stdcall-функция и нормальное имя в таблице экспорта.
MSG@4
А надо бы, по идее, чтобы было просто Msg
отсюда проблемы для использования таких библиотек в других, не ФриБейсиковых программах. Сам ФриБейсик понимает их нормально - безо всяких префиксов.
Выход есть, но не спасает:
дописать конвенцию cdecl в заголовке функции и алиасное имя и тогда мы получим нормальное имя (Msg), но тогда, к примеру, при вызове из VB функция отрабатывает нормально, но возникает другая ошибка: Bad dll calling convention, т. к. VB понимает stdcall. Выравнивание стека в самой функции не помогает... Вот так вот..
А хотелось бы, чтобы как в МАСМе - stdcall-функция и нормальное имя в таблице экспорта.
vbman- Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 42
Откуда : Украина, Кировоград
Всем спасибо! Сам разобрался:
Надо так:
теперь из ВБ, например, вызов будет такой:
- Код:
#Include "windows.bi"
#lang "fblite"
Option explicit
Extern "windows-ms" 'это ключевая строка!
Function Msg Alias "Msg" (ByVal s As ZString ptr) As Integer Export
MessageBox(0,s,0,MB_OK)
return(0L)
End Function
End Extern
теперь из ВБ, например, вызов будет такой:
- Код:
Private Declare Function Msg Lib "C:\dddd.dll" (ByVal s As String) As Long
Sub ee()
Msg "ssssss"
End Sub
vbman- Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 42
Откуда : Украина, Кировоград
Re: Экспорт из DLL
ну vbman, молодец! решил проблему. мне как раз было такое нужно. вот только я сделал так и оно тоже не пишет в експорты параметры функций:
код:
#Include "windows.bi"
Extern "windows-ms" 'это ключевая строка!
Function Msg Alias "Msg" (ByVal s As ZString ptr) As Integer Export
MessageBox(0,s,0,MB_OK)
return(0L)
End Function
End Extern
тоесть не надо работать с fblite.
короче надо больше мануалы читать! я ведь специально после прочтения твоего сообщения, залез в мануал, "Extern...End Extern", и там все как для дураков расписано, а мы тут пытаемся извращенски выкручиваться.
и не надо не кому писать, а надо внимательней читать. чесно говоря, я б туда не догадался залесть.
как раз, в скором времени хочу выпустить некую библиотечку, хочу, чтоб она была совместима как можно больше с разными языками программирования.
надо эту проблему будет описать какой-нибудь статьей. если сумею опишу, что такое extern "c", extern "windows", или в этом посте напишу как смогу. просто сегодня пора спать.
код:
#Include "windows.bi"
Extern "windows-ms" 'это ключевая строка!
Function Msg Alias "Msg" (ByVal s As ZString ptr) As Integer Export
MessageBox(0,s,0,MB_OK)
return(0L)
End Function
End Extern
тоесть не надо работать с fblite.
короче надо больше мануалы читать! я ведь специально после прочтения твоего сообщения, залез в мануал, "Extern...End Extern", и там все как для дураков расписано, а мы тут пытаемся извращенски выкручиваться.
и не надо не кому писать, а надо внимательней читать. чесно говоря, я б туда не догадался залесть.
как раз, в скором времени хочу выпустить некую библиотечку, хочу, чтоб она была совместима как можно больше с разными языками программирования.
надо эту проблему будет описать какой-нибудь статьей. если сумею опишу, что такое extern "c", extern "windows", или в этом посте напишу как смогу. просто сегодня пора спать.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|