Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамически загрузить библиотеку и передать указатель на функции / 7 сообщений из 7, страница 1 из 1
19.02.2016, 17:22
    #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
21.02.2016, 14:58
    #39176409
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамически загрузить библиотеку и передать указатель на функции
bdm77Добрый день, коллеги!
Есть задача в C# загрузить библиотеку (С++) и передать в нее класс с указателями на функции (callback).
.....

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

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

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

Фикировать в паияти нужно структуры данных пеоедаваемые в неупраляемый код при необходимости
...
Рейтинг: 0 / 0
22.02.2016, 10:11
    #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
22.02.2016, 11:54
    #39176652
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамически загрузить библиотеку и передать указатель на функции
bdm77,

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


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