Mapbasic: передача параметров функции по ссылке
- Juls
- Интересующийся
- Сообщения: 49
- Зарегистрирован: 02 авг 2010, 10:30
- Репутация: 1
Mapbasic: передача параметров функции по ссылке
Здравствуйте, Есть DLL библиотека написанная на C++, и там параметры функции передаются по ссылке. Есть ли возможность подключить ее к mapbasic?
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
а есть вообще только 2 способа передачи параметров в функцию - по значению и по ссылке. синтаксически в С++ различают по ссылке и указатели, но эти языковые нюансы сути не меняют: по ссылке - это значит - передается значение указателя.
для MB это означает, что параметры простых (т.е. не Type, не массивы, и не string) типов объявляются НЕ используя модификатор Byval.
относительно string - можно уточнить, м.б. что и изменилось, но даже изменяемую в DLL строку передаем как Byval (все равно сложные типы в MB передаются по ссылке, но адрес начала строки в сишном стиле формируется при использовании Byval), если нет, то стандартные системные Dll-ки (при их использовании) частенько рубят Mapinfo.
для MB это означает, что параметры простых (т.е. не Type, не массивы, и не string) типов объявляются НЕ используя модификатор Byval.
относительно string - можно уточнить, м.б. что и изменилось, но даже изменяемую в DLL строку передаем как Byval (все равно сложные типы в MB передаются по ссылке, но адрес начала строки в сишном стиле формируется при использовании Byval), если нет, то стандартные системные Dll-ки (при их использовании) частенько рубят Mapinfo.
- Juls
- Интересующийся
- Сообщения: 49
- Зарегистрирован: 02 авг 2010, 10:30
- Репутация: 1
Re: Mapbasic: передача параметров функции по ссылке
допустим в dll описана функция int MyFunction(char * sbuff, int *ival, char * s)
вызываю из мапбейсика след образом:
declare function MyFunction "Mydll.dll" (sbuff as string, ival as integer, comment as string) as integer
declare sub main
sub main
dim sbuff, comment as string,
ival, i_return as integer
sbuff="this is test"
i_return = MyFunction(sbuff,ival,comment)
end sub
возникает ошибка "внешняя библиотека не содержит функцию MyFunction" ? в чем проблема?
вызываю из мапбейсика след образом:
declare function MyFunction "Mydll.dll" (sbuff as string, ival as integer, comment as string) as integer
declare sub main
sub main
dim sbuff, comment as string,
ival, i_return as integer
sbuff="this is test"
i_return = MyFunction(sbuff,ival,comment)
end sub
возникает ошибка "внешняя библиотека не содержит функцию MyFunction" ? в чем проблема?
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
а две причины для такой ошибки:
1) ваша функция, которая MyFunction, является не экспортируемой;
2) ваша функция, которая MyFunction, называется совсем не MyFunction.
в первом случае, что называется - ССЗБ
во втором, чтоб не рыться в настройках компилятора и линковщика используйте такую замечательную штуку, как tdump.exe - посмотрите, что на самом деле записано в секции exports. И будте готовы, что компилятор напихал в имя функции кучу всякой фигни (в лучшем случае это будет знак подчеркивания в начале имени)
ну еще, вроде в строке
пропущено слово "Lib" перед именем файла dll
1) ваша функция, которая MyFunction, является не экспортируемой;
2) ваша функция, которая MyFunction, называется совсем не MyFunction.
в первом случае, что называется - ССЗБ
во втором, чтоб не рыться в настройках компилятора и линковщика используйте такую замечательную штуку, как tdump.exe - посмотрите, что на самом деле записано в секции exports. И будте готовы, что компилятор напихал в имя функции кучу всякой фигни (в лучшем случае это будет знак подчеркивания в начале имени)
ну еще, вроде в строке
Код: Выделить всё
declare function MyFunction "Mydll.dll" (sbuff as string, ival as integer, comment as string) as integer
- asgs
- Участник
- Сообщения: 89
- Зарегистрирован: 04 авг 2010, 06:35
- Репутация: 1
- Контактная информация:
Re: Mapbasic: передача параметров функции по ссылке
Обратите еще внимание, если dll-ку лепите в С++, используйте в описании функций способ вызова stdcall (влияет на порядок передачи параметров и очистку стека вызовов). По умолчанию с С++ используется fastcall, так что можно налететь на неприятные грабли.
Удачи.
Удачи.
Злобный йожег
- Juls
- Интересующийся
- Сообщения: 49
- Зарегистрирован: 02 авг 2010, 10:30
- Репутация: 1
Re: Mapbasic: передача параметров функции по ссылке
спасибо, за советы. способ вызова стоит stdcall. tdump показывает следующее:
Exports from MType.dll
1 exported name(s), 1 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00001010 1 0000 ?Char2Int@@YGHPADPAH0@Z
что означают символы после имени функции Char2Int? и как отключить декорирование функций в VSc++2008?
Exports from MType.dll
1 exported name(s), 1 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00001010 1 0000 ?Char2Int@@YGHPADPAH0@Z
что означают символы после имени функции Char2Int? и как отключить декорирование функций в VSc++2008?
- asgs
- Участник
- Сообщения: 89
- Зарегистрирован: 04 авг 2010, 06:35
- Репутация: 1
- Контактная информация:
Re: Mapbasic: передача параметров функции по ссылке
Для VC++ 2008 можно посмотреть как пример вот это: http://asgs.narod.ru/downloads/gpl/TiffMosaicSrc.rar
Там как раз библиотека под MapBasic.
Про декорацию имен функций - если мне не сильно изменяет склероз, нужно в файле *.def в секции EXPORTS создать список имен экспортируемых функций. В примере это должно быть.
Там как раз библиотека под MapBasic.
Про декорацию имен функций - если мне не сильно изменяет склероз, нужно в файле *.def в секции EXPORTS создать список имен экспортируемых функций. В примере это должно быть.
Злобный йожег
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
декорирование имен функций - это фишка C++, связанная с возможностью перегрузки функций.
в VS не знаю (как то не сложились отношения с компиляторами от MS), а в Борланд это решалось при объявлении функции примерно вот так:
extern "C" int Char2Int(...)
ну и stdcall cоответственно тоже надо...
все это прямые директивы компилятору, соответственно лазить во всякие доп. фалы не приходилось.
в VS не знаю (как то не сложились отношения с компиляторами от MS), а в Борланд это решалось при объявлении функции примерно вот так:
extern "C" int Char2Int(...)
ну и stdcall cоответственно тоже надо...
все это прямые директивы компилятору, соответственно лазить во всякие доп. фалы не приходилось.
- Juls
- Интересующийся
- Сообщения: 49
- Зарегистрирован: 02 авг 2010, 10:30
- Репутация: 1
Re: Mapbasic: передача параметров функции по ссылке
Спасибо Все получилось. с использованием def файла.
Подскажите еще можно ли както экспортировать в мапбейсик из dll константы определенные директивой #define?
Подскажите еще можно ли както экспортировать в мапбейсик из dll константы определенные директивой #define?
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
Будете смеятся, но у вас в dll нет констант, определенных "директивой #define" они существуют только в исходном коде, после компиляции - увы, нету их. Это чисто подстановочные значения, компилятор еще до собственно компиляции как только встретит значение из #define, сразу заменяет его выражением (именно текстом, даже не вычисляя выражения) из того же #define.
если хотите в программе на MB использовать такие же именованные константы, скопируйте их определения из с-шного кода в отдельный файл с раширением def (принято в MB), удалите символы # и ; - получите вполне такой заголовочный файл для MB. Подключать оператором Include. (аналогично mapbasic.def)
если хотите в программе на MB использовать такие же именованные константы, скопируйте их определения из с-шного кода в отдельный файл с раширением def (принято в MB), удалите символы # и ; - получите вполне такой заголовочный файл для MB. Подключать оператором Include. (аналогично mapbasic.def)
- Juls
- Интересующийся
- Сообщения: 49
- Зарегистрирован: 02 авг 2010, 10:30
- Репутация: 1
Re: Mapbasic: передача параметров функции по ссылке
Понятно, спасибо
вопрос еще такой, насколько я поняла декорирование функций необходимо для возможности перегрузки функций? т.е. в dll под mapbasic перегрузка функций не может быть использована?
вопрос еще такой, насколько я поняла декорирование функций необходимо для возможности перегрузки функций? т.е. в dll под mapbasic перегрузка функций не может быть использована?
- asgs
- Участник
- Сообщения: 89
- Зарегистрирован: 04 авг 2010, 06:35
- Репутация: 1
- Контактная информация:
Re: Mapbasic: передача параметров функции по ссылке
Насколько я помню, MapBasic не поддерживает перегрузку функций, по крайней мере пользовательских. Хотя встроенные функции, судя по всему, вполне себе перегруженные.
ЗЫ Блин, не совсем понял вопрос. Видимо, перегрузку функций из dll использовать будет затруднительно, поскольку в MapBasic-е они также рассматриваются как пользовательские.
ЗЫ Блин, не совсем понял вопрос. Видимо, перегрузку функций из dll использовать будет затруднительно, поскольку в MapBasic-е они также рассматриваются как пользовательские.
Злобный йожег
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
Внутри dll пожалуйста, можно использовать все возможности языка. А экспортировать перегруженные функции бесполезно - компилятор не даст экспортировать различные (а перегруженные функции все равно ведь различные, хотя и кажется, что одинаково называются) функции под одним именем.
-
- Новоприбывший
- Сообщения: 6
- Зарегистрирован: 04 окт 2011, 12:11
- Репутация: 0
- Откуда: Томск
Re: Mapbasic: передача параметров функции по ссылке
Добрый день.
Еще один вопрос в ту же тему.
Исходные данные: использую MapBasic 9.5 + Visual Studio 2010 (C#)
На C# сделана dll:
В MapBasic описываю эту внешнюю функцию (лежащую в dll):
В теле Sub Main программы на MapBasic вызываю эту функцию:
При запуске MapInfo весело отображает окошко с нулём (т.е. ВСЁ РАБОТАЕТ)
Далее в программе на MapBasic в декларативной секции метода убираем слово ByVal .
Получаем:
Цель: передавать в DLL не само значение переменной, а только ссылку на него. В перспективе DLL подправит значение переменной и MapInfo будет далее работать со значением обновленным в dll .
Проблема: после удаления ключевого слова ByVal при запуске программы на MapBasic появилась ошибка:
Вопрос: как в Visual Studio 2010 на C# сделать так, чтоб написанная dll все таки могла принимать переменные из MapBasic "по ссылке", а не "по значению" ?
Заранее благодарен за аргументированный ответ.
Еще один вопрос в ту же тему.
Исходные данные: использую MapBasic 9.5 + Visual Studio 2010 (C#)
На C# сделана dll:
Код: Выделить всё
namespace MIL
{ public class MIC
{ public static unsafe void GetMapIdFromDB(int Идентификатор_карты) // можно и без unsafe
{ MessageBox.Show(Convert.ToString(Идентификатор_карты)); }
}
}
Код: Выделить всё
Declare method GetMapIdFromDB Class "MIL.MIC" Lib "ClassLibrary1.dll" (ByVal maps_id as integer)
Код: Выделить всё
call GetMapIdFromDB(map_id)
(map_id предварительно описана как int и проинициализирована нулём)
Далее в программе на MapBasic в декларативной секции метода убираем слово ByVal .
Получаем:
Код: Выделить всё
Declare method GetMapIdFromDB Class "MIL.MIC" Lib "ClassLibrary1.dll" (maps_id as integer)
Проблема: после удаления ключевого слова ByVal при запуске программы на MapBasic появилась ошибка:
Код: Выделить всё
"Не найден метод public, static 'GetMapIdFromDB'. Проверьте имя метода и сигнатуру."
Заранее благодарен за аргументированный ответ.
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Mapbasic: передача параметров функции по ссылке
а вместо
void GetMapIdFromDB(int Идентификатор_карты)
в объявлении функции написать
void GetMapIdFromDB(int *идентификатор_карты) - т.е функция получит указатель
или так
void GetMapIdFromDB(int& идентификатор_карты) - т.е функция опять таки получит указатель, но обращаться с ним будет как с обычной переменной, т.е разименовывать не потребуется и код править тоже.
void GetMapIdFromDB(int Идентификатор_карты)
в объявлении функции написать
void GetMapIdFromDB(int *идентификатор_карты) - т.е функция получит указатель
или так
void GetMapIdFromDB(int& идентификатор_карты) - т.е функция опять таки получит указатель, но обращаться с ним будет как с обычной переменной, т.е разименовывать не потребуется и код править тоже.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость