Re: Вызов dll функций с переменным числом параметров
От: Кодт Россия  
Дата: 16.11.11 17:46
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Есть приложение, которое грузит плагины. При инициализации плагина оно вызывает из него функцию, посредством которой оно заполняет массив структур с описаниями экспортируемыми из плагина функциями. В структуре есть указатель на экспортируемую функцию и информация о количестве/типе ее параметров. Мне нужно создавать этот массив динамически, чтобы можно было использовать в dll любое количество функций с любым количеством параметров. Вопрос — как это сделать. Пока единственная идея — использовать в dll/плагине экспортируемые функции с переменным числом аргументов, например так:


Очень похоже на изобретение велосипеда, помноженное на кривую архитектуру.

Подобная задача уже решена, например, в COM — IDispatch сотоварищи.

Опять же, если это плагин, значит, его интерфейс уже известен. Приложение ожидает от плагина какие-то конкретные функции с какими-то конкретными сигнатурами. Может быть, не все эти функции реализованы...
В таком случае есть тупой, но рабочий подход! Пусть плагин экспортирует функции, как обычная dll (только без декорирования имён) — extern "C" __declspec(dllexport).
Приложение грузит эти функции через GetProcAddress, и если чего-то не находит, то и чёрт с ним.

А если плагин отдаёт библиотеку произвольных функций, которые приложение использует в каких-то скриптах... Тогда стоит сразу же определиться, что это за скрипты, и какой для данного скриптового движка естественный биндинг. И пусть плагин отдаёт информацию сразу готовую для движка.
Перекуём баги на фичи!
Вызов dll функций с переменным числом параметров
От: Аноним  
Дата: 16.11.11 12:01
Оценка:
Есть приложение, которое грузит плагины. При инициализации плагина оно вызывает из него функцию, посредством которой оно заполняет массив структур с описаниями экспортируемыми из плагина функциями. В структуре есть указатель на экспортируемую функцию и информация о количестве/типе ее параметров. Мне нужно создавать этот массив динамически, чтобы можно было использовать в dll любое количество функций с любым количеством параметров. Вопрос — как это сделать. Пока единственная идея — использовать в dll/плагине экспортируемые функции с переменным числом аргументов, например так:


extern "C" __declspec(dllexport)MyFunc(...)
{
  va_list vl;
  va_start(vl,amount);

  for (i=0;i<double_arg_count;i++)
  {
    double val=va_arg(vl,double);
  }

  for (i=0;i<int_arg_count;i++)
  {
    int val=va_arg(vl,double);
  }

  va_end(vl);
}


Так будет работать?
Re: Вызов dll функций с переменным числом параметров
От: sts  
Дата: 16.11.11 12:12
Оценка:
Да, будет.
Re: Вызов dll функций с переменным числом параметров
От: rus blood Россия  
Дата: 16.11.11 12:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть приложение, которое грузит плагины. При инициализации плагина оно вызывает из него функцию, посредством которой оно заполняет массив структур с описаниями экспортируемыми из плагина функциями. А>В структуре есть указатель на экспортируемую функцию и информация о количестве/типе ее параметров.


Эту информацию можно описать в виде интерфейса (структуры с абстрактными методами).
Плагин экспортирует реализации этих интерфейсов (конкретные реализации методов).


Мне нужно создавать этот массив динамически, чтобы можно было использовать в dll любое количество функций с любым количеством параметров. Вопрос — как это сделать. Пока единственная идея — использовать в dll/плагине экспортируемые функции с переменным числом аргументов, например так:

Непонятно.
Имею скафандр — готов путешествовать!
Re[2]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 12:26
Оценка:
Еще вопрос: как можно сделать, чтобы таких функций было создать "сколько угодно"? Объявить класс с открытой функцией от переменного количества аргументов, потом создать объекты этих классов, столько, сколько нужно, и затем привести указатели на эти функции к указателям на тип аналогичной глобальной функции?
Re[2]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 12:29
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Эту информацию можно описать в виде интерфейса (структуры с абстрактными методами).

RB>Плагин экспортирует реализации этих интерфейсов (конкретные реализации методов).
RB>Непонятно.

Задача в том, что саму программу изменить нельзя, можно только написать плагин.
Re: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 16.11.11 13:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вопрос — как это сделать.

Ну, например, можно возвращать указатель на статический массив и счётчик.
А можно их просто экспортировтаь даже.

Но как ты собираешься эти функции звать?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Вызов dll функций с переменным числом параметров
От: rus blood Россия  
Дата: 16.11.11 13:26
Оценка:
Здравствуйте, dandy, Вы писали:

D>Задача в том, что саму программу изменить нельзя, можно только написать плагин.


Если программу изменять нельзя, значит порядок работы с плагином уже фиксирован.
Тогда непонятно, к чему исходный вопрос.
Имею скафандр — готов путешествовать!
Re[3]: Вызов dll функций с переменным числом параметров
От: sts  
Дата: 16.11.11 13:35
Оценка:
Здравствуйте, dandy, Вы писали:

D>Еще вопрос: как можно сделать, чтобы таких функций было создать "сколько угодно"? Объявить класс с открытой функцией от переменного количества аргументов, потом создать объекты этих классов, столько, сколько нужно, и затем привести указатели на эти функции к указателям на тип аналогичной глобальной функции?


Можно например так (схематично):

// DLL:

typedef void (*my_func_t)(...);

static void my_func_1(...) {

}

static void my_func_2(...) {

}

static void my_func_3(...) {

}

static my_func_t my_func[] = {my_func_1, my_func_2, my_func_3};
static int counter;

void dllexport get_first(my_func_t*result) {
    counter = 0;
    get_next(result);
}

int dllexport get_next(my_func_t*result) {
    if (counter < ARRAY_SIZE(my_func)) {
        *result = my_func[counter];
        ++counter;
        return OK;
    }
    return ERROR;
}

// Application:

int main() {

    my_func_t func;
    for ( get_first(&func); get_next(&func) == OK; ) {
        func();
    }
}
Re[3]: Вызов dll функций с переменным числом параметров
От: rus blood Россия  
Дата: 16.11.11 13:47
Оценка:
Здравствуйте, dandy, Вы писали:

D>Еще вопрос: как можно сделать, чтобы таких функций было создать "сколько угодно"? Объявить класс с открытой функцией от переменного количества аргументов, потом создать объекты этих классов, столько, сколько нужно, и затем привести указатели на эти функции к указателям на тип аналогичной глобальной функции?


1. Функция класса не получится привести к "глобальной" функции.
Вернее, "об колено" можно, но работать не будет.

2. Сколько объектов класса не создавай, его метод (тело метода) будет в единственном экземпляре, с единственной точкой входа.
Имею скафандр — готов путешествовать!
Re[2]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 13:50
Оценка:
Здравствуйте, Erop, Вы писали:


E>Ну, например, можно возвращать указатель на статический массив и счётчик.

В дефолтных плагинах именно так оно и делается, но мне нужно больше.
С условиями задачи я напутал: тип функции один:
SomeVar Function(int, SomeStruct *);


E>А можно их просто экспортировтаь даже.

Из плагина прога экспортирует функции инициализации, по — видимому через GetProcAddress (или еще чего).
Прога вызывает эти функции после загрузки плагина. В одной из них плагин устанавливает проге указатель
на свой массив указателей на свои функции, после этого прога может вызывать эти функции из плагина.

E>Но как ты собираешься эти функции звать?


Как сделать в плагине не статический массив указателей на функции, а динамический массив указателей на функции: that is the question
Re[4]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 13:53
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, dandy, Вы писали:


RB>1. Функция класса не получится привести к "глобальной" функции.

RB>Вернее, "об колено" можно, но работать не будет.

RB>2. Сколько объектов класса не создавай, его метод (тело метода) будет в единственном экземпляре, с единственной точкой входа.


Угу. На pure С++ задача не решается.
Re[3]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 14:16
Оценка:
Здравствуйте, dandy, Вы писали:

E>>Но как ты собираешься эти функции звать?


D>Как сделать в плагине не статический массив указателей на функции, а динамический массив указателей на функции: that is the question


Есть некрасивое решение — определить в плагине много глобальных функций, возвращать проге массив указателей на часть из них. Но тогда количество функций плагина будет ограничено сверху, это не радует.
Re: Вызов dll функций с переменным числом параметров
От: MasterZiv СССР  
Дата: 16.11.11 14:40
Оценка:
On 11/16/2011 04:01 PM, Аноним 225 wrote:

> Есть приложение, которое грузит плагины. При инициализации плагина оно вызывает

> из него функцию, Мне нужно, чтобы можно было использовать в dll любое
> количество функций с любым количеством параметров. Вопрос — как это сделать.

Так же, как и в случае, когда нужно сделать то же самое, но без .DLL.
с и без .dll ничем не отличается.

> Пока единственная идея — использовать в dll/плагине экспортируемые функции с

> переменным числом аргументов, например так:
>
>
> extern "C" __declspec(dllexport)MyFunc(...)

>

> Так будет работать?

Да. Только у тебя функция неправильно оформлена -- как минимум один параметр у
неё должен быть. во-первых, от него и будут отсчитываться остальные параметры,
во-вторых, ты должен на основании значения этого параметра понять, сколько
у тебя всего других параметров.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Вызов dll функций с переменным числом параметров
От: MasterZiv СССР  
Дата: 16.11.11 14:42
Оценка:
On 11/16/2011 04:26 PM, dandy wrote:

> Еще вопрос: как можно сделать, чтобы таких функций было создать "сколько

> угодно"? Объявить класс с открытой функцией от переменного количества

Просто создавай сколько угодно таких функций, и всё.

Но должен предупредить, что вызов любых функций с переменным
кол-вом параметров -- плохая идея. Компилятор не будет
проверять правильность вызовов этих функций (передачу
параметров, их типы, кол-во).
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Вызов dll функций с переменным числом параметров
От: MasterZiv СССР  
Дата: 16.11.11 14:43
Оценка:
On 11/16/2011 04:19 PM, rus blood wrote:

> Мне нужно создавать этот массив динамически, чтобы можно было использовать в dll

> любое количество функций с любым количеством параметров. Вопрос — как это
> сделать. Пока единственная идея — использовать в dll/плагине экспортируемые
> функции с переменным числом аргументов, например так:

Ещё раз -- просто используй эти функции, и всё. ничего особенно для этого делать
не нужно.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Вызов dll функций с переменным числом параметров
От: rus blood Россия  
Дата: 16.11.11 14:57
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Просто создавай сколько угодно таких функций, и всё.


Как предлагаешь это делать в runtime ?
Имею скафандр — готов путешествовать!
Re[4]: Вызов dll функций с переменным числом параметров
От: rus blood Россия  
Дата: 16.11.11 14:59
Оценка:
Здравствуйте, dandy, Вы писали:

D>Есть некрасивое решение — определить в плагине много глобальных функций, возвращать проге массив указателей на часть из них. Но тогда количество функций плагина будет ограничено сверху, это не радует.


И что будет реализовано в этих функциях?
Заранее все алгоритмы напишешь?
Имею скафандр — готов путешествовать!
Re: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 15:08
Оценка:
Всем спасибо, буду смотреть в другую сторону.
Если что — правильное описание задачи (и некрасивое решение) в моих ответах Егору.
Re[5]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 15:11
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>И что будет реализовано в этих функциях?

RB>Заранее все алгоритмы напишешь?

Реализация будет в других плагинах, попроще, писать их будут пользователи.
Re[5]: Вызов dll функций с переменным числом параметров
От: MasterZiv СССР  
Дата: 16.11.11 15:28
Оценка:
On 11/16/2011 06:57 PM, rus blood wrote:

> Как предлагаешь это делать в runtime ?


Как угодно, в зависимости от желания. В рантайме конечно
скорее всего трудновато будет создавать сами функции (компилятор
там вызывать и прочее), но вот их описания -- кто ж запрещает ?
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 16:02
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Как угодно, в зависимости от желания. В рантайме конечно

MZ>скорее всего трудновато будет создавать сами функции (компилятор
MZ>там вызывать и прочее), но вот их описания -- кто ж запрещает ?

Там нет переменного количества параметров, это я ошибся, но желательно создавать сами функции, причем без вызова компилятора. На .Net это легко — делегат можно инициализировать как статической функцией, так и нестатической функцией класса. В общем, спасибо за ответы.
Re[3]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 16.11.11 16:13
Оценка:
Здравствуйте, dandy, Вы писали:

D>Как сделать в плагине не статический массив указателей на функции, а динамический массив указателей на функции: that is the question


А что за проблема?
Ну делаешь типа
typedef SomeVar TFunction(int, SomeStruct *);
std::vector<TFunction*> myArrayOfFunctions;
и вперёд...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Вызов dll функций с переменным числом параметров
От: sts  
Дата: 16.11.11 16:16
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Да. Только у тебя функция неправильно оформлена -- как минимум один параметр у

MZ>неё должен быть. во-первых, от него и будут отсчитываться остальные параметры,
MZ>во-вторых, ты должен на основании значения этого параметра понять, сколько
MZ>у тебя всего других параметров.

Не должно.
Если, к примеру, используется не передача количества в 1-м параметре, что чревато ошибками, а используется замыкающий параметр.
Типа того:
my_func("1", "2", "3", NULL);
Re[4]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 17:06
Оценка:
Здравствуйте, Erop, Вы писали:

E>А что за проблема?

E>Ну делаешь типа
typedef SomeVar TFunction(int, SomeStruct *);
E>std::vector<TFunction*> myArrayOfFunctions;
E>
и вперёд...


Да, но чем ты хочешь инициализировать этот вектор? Если ты хочешь написать очень много глобальных функций, то про это есть пост выше по ветке.
Re[2]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 18:46
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А если плагин отдаёт библиотеку произвольных функций, которые приложение использует в каких-то скриптах... Тогда стоит сразу же определиться, что это за скрипты, и какой для данного скриптового движка естественный биндинг. И пусть плагин отдаёт информацию сразу готовую для движка.


Тут уже где — то было написано, что приложение невозможно переделать. Этот плагин должен работать как переходник между кривым плагинным интерфейсом проги и .Net плагинами и должен предоставлять удобный .Net API для них. Вопрос в том, как красивее связать библиотеки функций .Net плагинов, число которых заранее неизвестно, с библиотекой функций, которую плагин — переходник должен передавать в прогу.
Re[6]: Вызов dll функций с переменным числом параметров
От: Кодт Россия  
Дата: 16.11.11 19:47
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Как угодно, в зависимости от желания. В рантайме конечно

MZ>скорее всего трудновато будет создавать сами функции (компилятор
MZ>там вызывать и прочее), но вот их описания -- кто ж запрещает ?

В рантайме, под конкретную платформу (i386/win32) — как нефиг делать.
ATL thunk <atlstdthunk.h>
или вот выжимка
http://rsdn.ru/forum/cpp/452414.1.aspx
Автор: Yess
Дата: 22.11.03

или на codeproject было ещё...
Перекуём баги на фичи!
Re[3]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 16.11.11 20:44
Оценка:
Здравствуйте, dandy, Вы писали:


D>Тут уже где — то было написано, что приложение невозможно переделать. Этот плагин должен работать как переходник между кривым плагинным интерфейсом проги и .Net плагинами и должен предоставлять удобный .Net API для них. Вопрос в том, как красивее связать библиотеки функций .Net плагинов, число которых заранее неизвестно, с библиотекой функций, которую плагин — переходник должен передавать в прогу.


Ну заверни дотнетного делегата в ком-объект, и отдавай наружу фабрику таких объектов...
Только, наверное, прийдётся аутпроц сервер делать, чтобы дотнет жилю
Или захачь интероп, как тебе Кодт советовал, а из плагина всё равно фабрику ком-объектов отдавай...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 16.11.11 21:03
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну заверни дотнетного делегата в ком-объект, и отдавай наружу фабрику таких объектов...

E>Только, наверное, прийдётся аутпроц сервер делать, чтобы дотнет жилю
E>Или захачь интероп, как тебе Кодт советовал, а из плагина всё равно фабрику ком-объектов отдавай...

Возможно интероп подойдет. Все, пошел спать!!!!!!!
Re[5]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 17.11.11 01:46
Оценка:
Здравствуйте, dandy, Вы писали:


D>Возможно интероп подойдет. Все, пошел спать!!!!!!!


А зачем тебе, чтобы управляемый код жил в ространстве нативного приложения?
Ради производительности? Они же мешать друг другу могут.
Как часто вызовы-то будут проходить?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Вызов dll функций с переменным числом параметров
От: dudkin  
Дата: 17.11.11 02:35
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Аноним, Вы писали:


А>>Вопрос — как это сделать.

E>Ну, например, можно возвращать указатель на статический массив и счётчик.

так эти три точки ... которые va_list и реализованы как массив указателей на аргументы c нулевым поинтером в конце
Re[6]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 06:01
Оценка:
Здравствуйте, Erop, Вы писали:

E>А зачем тебе, чтобы управляемый код жил в ространстве нативного приложения?

E>Ради производительности? Они же мешать друг другу могут.
E>Как часто вызовы-то будут проходить?

Прости за оффтоп, но ты когда — нибудь спишь?
Re[7]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 07:01
Оценка:
Здравствуйте, Кодт, Вы писали:

К>В рантайме, под конкретную платформу (i386/win32) — как нефиг делать.

К>ATL thunk <atlstdthunk.h>
К>или вот выжимка
К>http://rsdn.ru/forum/cpp/452414.1.aspx
Автор: Yess
Дата: 22.11.03

К>или на codeproject было ещё...

Посмотрел код, в vc 2008 это сделано уже и для x64 и пр. Только там __stdcall, мне нужно __cdecl.
Файл <atlstdthunk.h>
Re[7]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 17.11.11 07:33
Оценка:
Здравствуйте, dandy, Вы писали:



D>Прости за оффтоп, но ты когда — нибудь спишь?

Раз в несколько дней
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 17.11.11 07:53
Оценка:
Здравствуйте, dandy, Вы писали:


D>Посмотрел код, в vc 2008 это сделано уже и для x64 и пр. Только там __stdcall, мне нужно __cdecl.

D>Файл <atlstdthunk.h>

Очень трудно понять, что же тебе надо.
Я так понял, что у тебя есть какое-то нативное приложение, у которого есть интерфейс к своим плагинам.
И ты хочешь предоставить возможность динамически плодить плагины на дотнете.
В твоём понимании дотнетовская функция для плагина -- это делегат.
Это то, что я понял, не факт, что правильно.
Чего я не понял, так это того, входит ли в описание функции для плагина указатель на данные? То есть можно ли конкретный делегат идентифицировать по указатею на данные, а не на код?

Собственно задача распадается на три куска.
1) Как в пространстве материнского приложения запустить дотнет? Мой ответ: не надо так делать. Дотнет тяжёлая прожорливая хрень. Она можжет нагнуть приложение, могут повылазить невыявленные при стресс-тестировании приложения баги, и стабильно это может так и не заработать. Намного надёжнее запускать дотнет в другом процессе, а интероп сделать через межпроцессный вызов, например через RPC, но под виндой прямее ком, КМК.

2) Как организовать вызов из нативного кода плагинной DLL дотнетовского делегата. Ясно, что в С++ части будет какой-то объект, который будет иметь внутри указатель на делегат, и дёргать его. Но если в (1) заюзать ком, то этот кусок выраждается до банального COMPtr

3) Как продать объекты из (2) приложению, под видом функций. Собственно, если интерфейс приложения к плагинам позволяет идентиицировать конкретную функцию указателем на данные, а не на код, то нет проблем. В качестве указателя на функцию отдаёшь функцию, которая ждёт указатель на данные, досттаёт из него нужный ком-интерфейс и зовёт функцию, дёргающую, в конце концов делегата.

Но я так понял, что интерфейс приложения к плагинам подраазумевает, что функцию определяет именно указатель на код, а указатель на данные использовать нельзя.
Тогда есть два варианта.
Вариат 1.
Пул функций.

Тут либо шаблоны, либо макросы, либо генератор (или ручки вместо генератора)

Вариант 2
Генерённый код.

Тут тоже не сложно.
Типа пишем шаблон кода, который делает
push [подставить ID конкретной функции]
jp [функция на С++, которая ID получит как аргумент и разрулит...]

Заводим память, в которую можн писать и которую можно исполнять и плодим эти thunk-функции в том количестве, в котором нам надо...

Я вообще верно понял твою задачу?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 09:10
Оценка:
Здравствуйте, Erop, Вы писали:


E>Очень трудно понять, что же тебе надо.

E>Я так понял, что у тебя есть какое-то нативное приложение, у которого есть интерфейс к своим плагинам.
E>И ты хочешь предоставить возможность динамически плодить плагины на дотнете.

Нужно динамически загружать все плагины, у которые используют дотнетовские классы моего плагина.

E>В твоём понимании дотнетовская функция для плагина -- это делегат.

E>Это то, что я понял, не факт, что правильно.

Не так, но это неважно.

E>Чего я не понял, так это того, входит ли в описание функции для плагина указатель на данные? То есть можно ли конкретный делегат идентифицировать по указатею на данные, а не на код?


Да входит. Но идентифицировать нужно по указателю на функцию.

E>Собственно задача распадается на три куска.

E>1) Как в пространстве материнского приложения запустить дотнет? Мой ответ: не надо так делать. Дотнет тяжёлая прожорливая хрень. Она можжет нагнуть приложение, могут повылазить невыявленные при стресс-тестировании приложения баги, и стабильно это может так и не заработать. Намного надёжнее запускать дотнет в другом процессе, а интероп сделать через межпроцессный вызов, например через RPC, но под виндой прямее ком, КМК.

Все должно быть в одном процессе.

E>2) Как организовать вызов из нативного кода плагинной DLL дотнетовского делегата. Ясно, что в С++ части будет какой-то объект, который будет иметь внутри указатель на делегат, и дёргать его. Но если в (1) заюзать ком, то этот кусок выраждается до банального COMPtr



E>3) Как продать объекты из (2) приложению, под видом функций. Собственно, если интерфейс приложения к плагинам позволяет идентиицировать конкретную функцию указателем на данные, а не на код, то нет проблем. В качестве указателя на функцию отдаёшь функцию, которая ждёт указатель на данные, досттаёт из него нужный ком-интерфейс и зовёт функцию, дёргающую, в конце концов делегата.


Там через делегаты IMHO будет сложно для пользователей. Это я еще не смотрел, но IMHO проще будет через рефлексию и производные классы. COM не пойдет по той же причине.

E>Но я так понял, что интерфейс приложения к плагинам подраазумевает, что функцию определяет именно указатель на код, а указатель на данные использовать нельзя.


Да

E>Тогда есть два варианта.

E>Вариат 1.
E>Пул функций.

E>Тут либо шаблоны, либо макросы, либо генератор (или ручки вместо генератора)


Просто, но некрасиво, писал уже об этом.

E>Вариант 2

E>Генерённый код.

E>Тут тоже не сложно.

E>Типа пишем шаблон кода, который делает
E>push [подставить ID конкретной функции]
E>jp [функция на С++, которая ID получит как аргумент и разрулит...]

E>Заводим память, в которую можн писать и которую можно исполнять и плодим эти thunk-функции в том количестве, в котором нам надо...

В ассемблере я не силен к сожалению.

Есть еще 3 — й вариант — чистый .NET

E>Я вообще верно понял твою задачу?

Re[8]: Вызов dll функций с переменным числом параметров
От: Кодт Россия  
Дата: 17.11.11 09:29
Оценка:
Здравствуйте, dandy, Вы писали:

D>Посмотрел код, в vc 2008 это сделано уже и для x64 и пр. Только там __stdcall, мне нужно __cdecl.

D>Файл <atlstdthunk.h>

Ну и что, что __stdcall.
Посмотрим на байткод функции такого вида
typedef int __stdcall CALLEE(intptr_t cookie, va_list args);

int __cdecl thunk(...)
{
  va_list args;
  va_start(args);
  return callee(cookie, args);
}

и напишем свой собственный генератор санок.

Причём можно параметризовать его не двумя значениями (адрес функции callee и произвольный указатель cookie), а одним (cookie — указатель на интерфейс)
struct ICookie
{
  virtual int call(va_list args) = 0;
};
int __stdcall callee(ICookie* cookie, va_list args) { return cookie->call(args); }

можно, конечно, напрямую из thunk вызывать виртуальную функцию, но это слишком много байт

Кстати говоря, поскольку __cdecl предполагает очистку стека вызывающей стороной, то концевой вызов можно заменить на прыжок.
thunk proc
  ; на стеке сейчас: (return-to) (arg1) (arg2) ... (argN)
  ;                  ^-- esp     ^-- esp+4

  pop  eax ; (return-to)
  push esp ; (&arg1)
  push cookie
  push eax ; (return-to)
  ; теперь на стеке: (return-to) (cookie) (&arg1) (arg1) (arg2) ... (argN)
  jmp  callee
  ; по завершении - перейдём на (return-to) инструкцией ret 8 (очистив два своих аргумента)
  ; и оставим на стеке (arg1)...(argN)
  ; а вызывающая сторона почистит стек до argN уже сама
thunk endp

Аналогично делается для x64 и ARM.
(Только, насколько я помню, у арма stdcall такой же, как и fastcall, т.е. два первых аргумента передаются через регистры)
Перекуём баги на фичи!
Re[9]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 09:37
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, dandy, Вы писали:


D>>Посмотрел код, в vc 2008 это сделано уже и для x64 и пр. Только там __stdcall, мне нужно __cdecl.

D>>Файл <atlstdthunk.h>

К>Ну и что, что __stdcall.

К>Посмотрим на байткод функции такого вида
К>
К>typedef int __stdcall CALLEE(intptr_t cookie, va_list args);

К>int __cdecl thunk(...)
К>{
К>  va_list args;
К>  va_start(args);
К>  return callee(cookie, args);
К>}
К>

К>и напишем свой собственный генератор санок.

К>Причём можно параметризовать его не двумя значениями (адрес функции callee и произвольный указатель cookie), а одним (cookie — указатель на интерфейс)

К>
К>struct ICookie
К>{
К>  virtual int call(va_list args) = 0;
К>};
К>int __stdcall callee(ICookie* cookie, va_list args) { return cookie->call(args); }
К>

К>можно, конечно, напрямую из thunk вызывать виртуальную функцию, но это слишком много байт

К>Кстати говоря, поскольку __cdecl предполагает очистку стека вызывающей стороной, то концевой вызов можно заменить на прыжок.

К>
К>thunk proc
К>  ; на стеке сейчас: (return-to) (arg1) (arg2) ... (argN)
К>  ;                  ^-- esp     ^-- esp+4

К>  pop  eax ; (return-to)
К>  push esp ; (&arg1)
К>  push cookie
К>  push eax ; (return-to)
К>  ; теперь на стеке: (return-to) (cookie) (&arg1) (arg1) (arg2) ... (argN)
К>  jmp  callee
К>  ; по завершении - перейдём на (return-to) инструкцией ret 8 (очистив два своих аргумента)
К>  ; и оставим на стеке (arg1)...(argN)
К>  ; а вызывающая сторона почистит стек до argN уже сама
К>thunk endp
К>

К>Аналогично делается для x64 и ARM.
К>(Только, насколько я помню, у арма stdcall такой же, как и fastcall, т.е. два первых аргумента передаются через регистры)

Ассемблер не знаю, увы, так что с этим связываться неохота.
Re[10]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 17.11.11 10:05
Оценка:
Здравствуйте, dandy, Вы писали:

D>В ассемблере я не силен к сожалению.

Сделай шаблонный или макросный пул функций-редеректоров...

D>Есть еще 3 — й вариант — чистый .NET


Если ты можешь само приложение переписывать, то в чём вообще запара? Сделай удобный интерфейс к плагинам (чтобы функция определлась ПАРОЙ указателей: указателем на код и указатеем на данные, который при вызове передаётся в эту самую указуемую функцию) и не страдай...

E>>Я вообще верно понял твою задачу?

D>

Мне так кажется, что если ты понятно расскажешь что делаешь, помочь теюе будет намного легче...

Да, и, кстати, объясни мне, зачем дотнет запускать в своём нативном процессе? Это какую вгоду приносит? Ну и в любом случае ком и так и так умеет. На дотнете ком-объекты пишутся стандартно, есть куча кода, который это поддерживает и облегчает, так что мне лично не понятно, зачем гонять через интерфейс плагина какие-то хреновины, а не комовские интерфейсы...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[11]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 10:33
Оценка:
Здравствуйте, Erop, Вы писали:


D>>Есть еще 3 — й вариант — чистый .NET


E>Если ты можешь само приложение переписывать, то в чём вообще запара? Сделай удобный интерфейс к плагинам (чтобы функция определлась ПАРОЙ указателей: указателем на код и указатеем на данные, который при вызове передаётся в эту самую указуемую функцию) и не страдай...


Не могу я его переписать. Если мог бы, все было бы просто. Грузил бы .NET плагины из C++ managed dll. Мечты...

E>Мне так кажется, что если ты понятно расскажешь что делаешь, помочь теюе будет намного легче...


E>Да, и, кстати, объясни мне, зачем дотнет запускать в своём нативном процессе? Это какую вгоду приносит? Ну и в любом случае ком и так и так умеет. На дотнете ком-объекты пишутся стандартно, есть куча кода, который это поддерживает и облегчает, так что мне лично не понятно, зачем гонять через интерфейс плагина какие-то хреновины, а не комовские интерфейсы...


Нужно через мой плагин обеспечить максимально удобный .NET API для работы с прогой из пользовательских .NET библиотек классов. COM сложен в использовании, можно сделать намного проще для пользователя, поэтому он сразу отпадает.
Re[12]: Вызов dll функций с переменным числом параметров
От: Erop Россия  
Дата: 17.11.11 10:47
Оценка:
Здравствуйте, dandy, Вы писали:

D>Нужно через мой плагин обеспечить максимально удобный .NET API для работы с прогой из пользовательских .NET библиотек классов. COM сложен в использовании, можно сделать намного проще для пользователя, поэтому он сразу отпадает.


А зачем пользователю показывать ком? Но можно и не ком. Это вообще не важно. Есть много способов интеропа. Я бы выбирал самый распространённый и всё.

Ты задачу-то объяснишь?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[13]: Вызов dll функций с переменным числом параметров
От: dandy  
Дата: 17.11.11 11:13
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ты задачу-то объяснишь?


Да уже и не нужно. Напишу — таки кодогенератор. Усложнять себе дороже получится.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.