Страница 1 из 2
Mapbasic: передача параметров функции по ссылке
Добавлено: 24 июн 2011, 14:19
Juls
Здравствуйте, Есть DLL библиотека написанная на C++, и там параметры функции передаются по ссылке. Есть ли возможность подключить ее к mapbasic?
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 27 июн 2011, 05:32
SergS
а есть вообще только 2 способа передачи параметров в функцию - по значению и по ссылке. синтаксически в С++ различают по ссылке и указатели, но эти языковые нюансы сути не меняют: по ссылке - это значит - передается значение указателя.
для MB это означает, что параметры простых (т.е. не Type, не массивы, и не string) типов объявляются НЕ используя модификатор Byval.
относительно string - можно уточнить, м.б. что и изменилось, но даже изменяемую в DLL строку передаем как Byval (все равно сложные типы в MB передаются по ссылке, но адрес начала строки в сишном стиле формируется при использовании Byval), если нет, то стандартные системные Dll-ки (при их использовании) частенько рубят Mapinfo.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 27 июн 2011, 15:51
Juls
допустим в 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" ? в чем проблема?
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 04:53
SergS
а две причины для такой ошибки:
1) ваша функция, которая MyFunction, является не экспортируемой;
2) ваша функция, которая MyFunction, называется совсем не MyFunction.
в первом случае, что называется - ССЗБ

во втором, чтоб не рыться в настройках компилятора и линковщика используйте такую замечательную штуку, как tdump.exe - посмотрите, что на самом деле записано в секции exports. И будте готовы, что компилятор напихал в имя функции кучу всякой фигни (в лучшем случае это будет знак подчеркивания в начале имени)
ну еще, вроде в строке
Код: Выделить всё
declare function MyFunction "Mydll.dll" (sbuff as string, ival as integer, comment as string) as integer
пропущено слово
"Lib" перед именем файла dll
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 06:06
asgs
Обратите еще внимание, если dll-ку лепите в С++, используйте в описании функций способ вызова stdcall (влияет на порядок передачи параметров и очистку стека вызовов). По умолчанию с С++ используется fastcall, так что можно налететь на неприятные грабли.
Удачи.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 11:12
Juls
спасибо, за советы. способ вызова стоит 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?
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 12:00
asgs
Для VC++ 2008 можно посмотреть как пример вот это:
http://asgs.narod.ru/downloads/gpl/TiffMosaicSrc.rar
Там как раз библиотека под MapBasic.
Про декорацию имен функций - если мне не сильно изменяет склероз, нужно в файле *.def в секции EXPORTS создать список имен экспортируемых функций. В примере это должно быть.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 12:13
SergS
декорирование имен функций - это фишка C++, связанная с возможностью перегрузки функций.
в VS не знаю (как то не сложились отношения с компиляторами от MS), а в Борланд это решалось при объявлении функции примерно вот так:
extern "C" int Char2Int(...)
ну и stdcall cоответственно тоже надо...
все это прямые директивы компилятору, соответственно лазить во всякие доп. фалы не приходилось.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 15:11
Juls
Спасибо Все получилось. с использованием def файла.
Подскажите еще можно ли както экспортировать в мапбейсик из dll константы определенные директивой #define?
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 15:45
SergS
Будете смеятся, но у вас в dll нет констант, определенных "директивой #define" они существуют только в исходном коде, после компиляции - увы, нету их. Это чисто подстановочные значения, компилятор еще до собственно компиляции как только встретит значение из #define, сразу заменяет его выражением (именно текстом, даже не вычисляя выражения) из того же #define.
если хотите в программе на MB использовать такие же именованные константы, скопируйте их определения из с-шного кода в отдельный файл с раширением def (принято в MB), удалите символы # и ; - получите вполне такой заголовочный файл для MB. Подключать оператором Include. (аналогично mapbasic.def)
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 28 июн 2011, 16:50
Juls
Понятно, спасибо
вопрос еще такой, насколько я поняла декорирование функций необходимо для возможности перегрузки функций? т.е. в dll под mapbasic перегрузка функций не может быть использована?
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 29 июн 2011, 04:14
asgs
Насколько я помню, MapBasic не поддерживает перегрузку функций, по крайней мере пользовательских. Хотя встроенные функции, судя по всему, вполне себе перегруженные.
ЗЫ Блин, не совсем понял вопрос. Видимо, перегрузку функций из dll использовать будет затруднительно, поскольку в MapBasic-е они также рассматриваются как пользовательские.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 29 июн 2011, 05:11
SergS
Внутри dll пожалуйста, можно использовать все возможности языка. А экспортировать перегруженные функции бесполезно - компилятор не даст экспортировать различные (а перегруженные функции все равно ведь различные, хотя и кажется, что одинаково называются) функции под одним именем.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 04 окт 2011, 12:56
Vladislav
Добрый день.
Еще один вопрос в ту же тему.
Исходные данные: использую 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(Идентификатор_карты)); }
}
}
В MapBasic описываю эту внешнюю функцию (лежащую в dll):
Код: Выделить всё
Declare method GetMapIdFromDB Class "MIL.MIC" Lib "ClassLibrary1.dll" (ByVal maps_id as integer)
В теле Sub Main программы на MapBasic вызываю эту функцию:
Код: Выделить всё
call GetMapIdFromDB(map_id)
(map_id предварительно описана как int и проинициализирована нулём)
При запуске MapInfo весело отображает окошко с нулём (т.е.
ВСЁ РАБОТАЕТ)
Далее в программе на MapBasic в декларативной секции метода убираем слово
ByVal .
Получаем:
Код: Выделить всё
Declare method GetMapIdFromDB Class "MIL.MIC" Lib "ClassLibrary1.dll" (maps_id as integer)
Цель: передавать в DLL не само значение переменной, а только ссылку на него. В перспективе DLL подправит значение переменной и MapInfo будет далее работать со значением обновленным в dll .
Проблема: после удаления ключевого слова ByVal при запуске программы на MapBasic появилась ошибка:
Код: Выделить всё
"Не найден метод public, static 'GetMapIdFromDB'. Проверьте имя метода и сигнатуру."
Вопрос: как в
Visual Studio 2010 на C# сделать так, чтоб написанная dll все таки могла принимать переменные из MapBasic
"по ссылке", а не
"по значению" ?
Заранее благодарен за аргументированный ответ.
Re: Mapbasic: передача параметров функции по ссылке
Добавлено: 04 окт 2011, 14:10
SergS
а вместо
void GetMapIdFromDB(int Идентификатор_карты)
в объявлении функции написать
void GetMapIdFromDB(int *идентификатор_карты) - т.е функция получит указатель
или так
void GetMapIdFromDB(int& идентификатор_карты) - т.е функция опять таки получит указатель, но обращаться с ним будет как с обычной переменной, т.е разименовывать не потребуется и код править тоже.