powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамически загрузить библиотеку и передать указатель на функции
7 сообщений из 7, страница 1 из 1
Динамически загрузить библиотеку и передать указатель на функции
    #39175501
bdm77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, коллеги!

Есть задача в C# загрузить библиотеку (С++) и передать в нее класс с указателями на функции (callback).

Все написал, все передается, но почему то указатели на ф-ции в библиотеке пропадают. С кодом будет понятнее

C#
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
public class HWIL_PluginInterface{

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate int set_camera_rate_abs_t(uint cameraID, float yaw, float pitch, float roll);	
}

public struct plugin_interface {

	public HWIL_PluginInterface.set_camera_rate_abs_t set_camera_rate_abs;

	public void RegistryCallback(PluginCallback pluginCallback)
	{
		set_camera_rate_abs += pluginCallback.camera_rate_abs;
	}	
}

public class PluginCallback{

	public int camera_rate_abs(uint cameraID, float yaw, float pitch, float roll)
        {            
            m_log.Debug("camera_rate: CameraId = " + cameraID + ", yaw = " + yaw.ToString() + ", pitch = " + pitch + ", roll = " + roll);
			
			
            return 0;
        }		
}

public int main(){

    [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl) ]        
    internal delegate HWIL_PluginInterface.result_enum PluginDelegate( MarshalAs(UnmanagedType.Struct)]
                                                                       ref plugin_interface pluginInterface,
                                                                       char[] cf_path,
                                                                       IntPtr usr);

     plugin_interface plugin = new plugin_interface();
     PluginCallback pluginCallback = new PluginCallback();
	
     plugin.RegistryCallback(pluginCallback):
	
     IntPtr m_pluginProc = GetProcAddress(plugin, "load_plugin");
		
     var loadPlugin = (PluginDelegate)Marshal.GetDelegateForFunctionPointer(m_pluginProc, typeof(PluginDelegate));

     loadPlugin(ref plugin, null, IntPtr.Zero);	
}




С++
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
.h
typedef int(*set_camera_rate_abs_t) (unsigned int cameraID, float yaw, float pitch, float roll);

typedef struct{
   set_camera_rate_abs_t 
        set_camera_rate_abs;
}


.cpp
class PluginAdapter
{
	plugin_interface* m_interface;
	public:
	PluginAdapter(plugin_interface* ptr)
		: m_interface(ptr)
	{
	}

	~PluginAdapter()
	{	
	}

	void load()
	{
		printf("Proxy.Plugin: call camera_state_callback\n");	
		printf("load_plugin: m_interface %d\n", m_interface);
		printf("load_plugin: m_interface->set_camera_rate_abs: %d\n", (long)m_interface->set_camera_rate_abs);
		printf("load_plugin: Proxy.Plugin: Make first call to CAMERA_MODE_RATE\n");

		m_interface->set_camera_rate_abs(0, 5.2, 2.7, 0.2);
		m_thread = new boost::thread( boost::bind(&PluginAdapter::RunCommand, this));

		boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
	}

	void RunCommand()
	{		
		printf("RunCommand: pluginPtr: %d\n", (long)m_interface);
		printf("RunCommand: pluginPtr->set_camera_rate_abs: %d\n", (long)m_interface->set_camera_rate_abs);

		while(true)
		{
			printf("RunCommand: pluginPtr: %d\n", (long)m_interface);
			printf("RunCommand: pluginPtr->set_camera_rate_abs: %d\n\n", (long)m_interface->set_camera_rate_abs);
			
			//m_interface->set_camera_rate_abs(0, 5.0, 20.5, 10.7);
			boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
		}
	}

private:
	boost::thread* m_thread;
};

PluginAdapter* g_plugin;

extern "C" __declspec(dllexport) int load_plugin(plugin_interface *ptr_interface, const char *cf_path, void *usr) 
{	
	g_plugin = new PluginAdapter(ptr_interface);
	g_plugin->load();
	
        printf("load_plugin: ptr_interface->set_camera_rate_abs: %d\n\n", (long)ptr_interface->set_camera_rate_abs);
	boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
	printf("Proxy.Exit\n");
	return RESULT_OK;
}



Указатель на функцию ptr_interface->set_camera_rate_abs() "живет" до тех пор, пока не вышли из метода load_plugin .
После выхода адрес ptr_interface тот же, а вот указатель на функцию изменяется на "мусор" . При этом в программе на С# все адреса те же.

Если я в методе load_plugin() при создании объекта new PluginAdapter(*ptr_interface); передаю не указатель на объект, а сам объект, то программа работает корректно.

Помогите пожалуйста, мне надо передавать указатель на объкт и что бы указатели на ф-ции не умирали.

Спасибо!!
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176409
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bdm77Добрый день, коллеги!
Есть задача в C# загрузить библиотеку (С++) и передать в нее класс с указателями на функции (callback).
.....

могу ошибаться(давно было дело), но Вам нужно анмэнэджет код позвать анмэнэджет кодом. Т.е. под си бимолем делаете си плас пласный код обёртку который будет это всё делать(звать функцию). Термин "время жизни" понимать. И маршалинг делать средствами си бимоля(так быстрее).

(круглый)
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176418
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolobok0могу ошибаться
никаких обёрток, c# маршаллер без особых хлопот коллбэки позволяет сделать
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176453
bdm77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропилkolobok0могу ошибаться
никаких обёрток, c# маршаллер без особых хлопот коллбэки позволяет сделать

c# маршаллер отлично работает, но куда деваются указатели, после выхода из метода load_plugin .
Я знаю что такое время жизни переменной, но тут уже начал в этом сомневаться..
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176489
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bdm77,

Фикировать в паияти нужно структуры данных пеоедаваемые в неупраляемый код при необходимости
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176601
bdm77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

Прочитал, что нужно копировать полученный объект:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
extern "C" __declspec(dllexport) int load_plugin(plugin_interface *ptr_interface, const char *cf_path, void *usr) 
{	
        plugin_interface *m_interface = new plugin_interface();
        m_interface->set_camera_rate_abs = ptr_interface->set_camera_rate_abs;

	g_plugin = new PluginAdapter(m_interface);
	g_plugin->load();
	
	printf("Proxy.Exit\n");
	return RESULT_OK;
}



Все работает!!


"Фикировать в паияти нужно структуры данных пеоедаваемые в неупраляемый код при необходимости" -
чем можно ее фикировать??
...
Рейтинг: 0 / 0
Динамически загрузить библиотеку и передать указатель на функции
    #39176652
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bdm77,

gchandle
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамически загрузить библиотеку и передать указатель на функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]