Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 10.06.13 09:17
Оценка:
Добрый день.
Библиотека (классическая, не СОМ) возвращает ссылку на класс:

long GetClassObject()
{
*pInterface= new CAddInNative;
return (long)*pInterface;
}

в программе на C# эту ссылку я получил присвоив типу IntPtr:

[DllImport("....dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetClassObject();

Вопрос:
Как вызвать методы класса CAddinNative? Т.е. как описать этот полученный класс на C#?

Заранее благодарен за помощь.
mirag
Re: Работа со ссылкой на класс.
От: AntoxaM  
Дата: 10.06.13 12:41
Оценка:
Здравствуйте, mirag_ga, Вы писали:

_>Добрый день.

_>Библиотека (классическая, не СОМ) возвращает ссылку на класс:
_>long GetClassObject()
_>{
_>*pInterface= new CAddInNative;
_>return (long)*pInterface;
_>}
_>в программе на C# эту ссылку я получил присвоив типу IntPtr:
_>[DllImport("....dll", CharSet = CharSet.Auto, SetLastError = true)]
_>private static extern IntPtr GetClassObject();

_>Вопрос:

_>Как вызвать методы класса CAddinNative? Т.е. как описать этот полученный класс на C#?

_>Заранее благодарен за помощь.


Напрямую, в принципе можно, но крайне осторожно.

Лучше создать обёртку и в C# использовать её.
Обёртку можно сделать на чистом С, либо с помощью COM, либо C++/CLI.
Пример для С++/CLI: http://msdn.microsoft.com/en-us/library/ms235281(v=vs.110).aspx
Re[2]: Работа со ссылкой на класс.
От: Аноним  
Дата: 10.06.13 13:50
Оценка:
Здравствуйте, AntoxaM, Вы писали:
Благодарю за ответ.

AM>Напрямую, в принципе можно, но крайне осторожно.

Вопрос: В чем осторожность? У меня при вызовах метода всегда дает ошибку разрушения памяти.
Я использовал и прямое присвоение и через Marshal.PtrToStructure использовав в качестве параметра класс.
И через Marshal.GetDelegateForFunctionPointer (хотя в MSDN написано что этот метод нельзя применять при импорте из С++),
и через Interface — результат то же — разрушение памяти. (не совпадают наверняка адреса методов в памяти.)
Мне кажется необходимо при импорте PtrToSructure каким то образом упаковать (распаковать, поставить размер) импортируемого класса.

AM>Лучше создать обёртку и в C# использовать её.

AM>Обёртку можно сделать на чистом С, либо с помощью COM, либо C++/CLI.
Каким образом через СОМ? Стандартные СОМ объекты, написанные на С++ спокойно работали используя Activator.CreateInstance, в данном случае постоянно выдает ошибку, не правильно определен тип.
AM>Пример для С++/CLI: http://msdn.microsoft.com/en-us/library/ms235281(v=vs.110).aspx
Необходимо написать на C# импорт всех функций возвращаемого класса.
Re[3]: Работа со ссылкой на класс.
От: AntoxaM  
Дата: 10.06.13 15:26
Оценка:
Здравствуйте, Аноним, Вы писали:

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

А>Благодарю за ответ.

AM>>Напрямую, в принципе можно, но крайне осторожно.

А>Вопрос: В чем осторожность? У меня при вызовах метода всегда дает ошибку разрушения памяти.
А>Я использовал и прямое присвоение и через Marshal.PtrToStructure использовав в качестве параметра класс.
А>И через Marshal.GetDelegateForFunctionPointer (хотя в MSDN написано что этот метод нельзя применять при импорте из С++),
А>и через Interface — результат то же — разрушение памяти. (не совпадают наверняка адреса методов в памяти.)
А>Мне кажется необходимо при импорте PtrToSructure каким то образом упаковать (распаковать, поставить размер) импортируемого класса.

Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде. Поэтому не стал даже пробовать и посоветовать ничего не могу.

AM>>Лучше создать обёртку и в C# использовать её.

AM>>Обёртку можно сделать на чистом С, либо с помощью COM, либо C++/CLI.
А>Каким образом через СОМ? Стандартные СОМ объекты, написанные на С++ спокойно работали используя Activator.CreateInstance, в данном случае постоянно выдает ошибку, не правильно определен тип.
Создать COM класс и из него вызывать методы исходного С++ класса.
AM>>Пример для С++/CLI: http://msdn.microsoft.com/en-us/library/ms235281(v=vs.110).aspx
А>Необходимо написать на C# импорт всех функций возвращаемого класса.
Насколько я понимаю, это так или иначе в любом варианте придётся делать
Re[4]: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 11.06.13 05:56
Оценка:
Здравствуйте, AntoxaM, Вы писали:
Еще раз спасибо за участие.
AM>>>Напрямую, в принципе можно, но крайне осторожно.
А>>Вопрос: В чем осторожность? У меня при вызовах метода всегда дает ошибку разрушения памяти.
А>>Я использовал и прямое присвоение и через Marshal.PtrToStructure использовав в качестве параметра класс.
А>>И через Marshal.GetDelegateForFunctionPointer (хотя в MSDN написано что этот метод нельзя применять при импорте из С++),
А>>и через Interface — результат то же — разрушение памяти. (не совпадают наверняка адреса методов в памяти.)
А>>Мне кажется необходимо при импорте PtrToSructure каким то образом упаковать (распаковать, поставить размер) импортируемого класса.

AM>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде. Поэтому не стал даже пробовать и посоветовать ничего не могу.


В любом случае ничего и так не получилось....

AM>>>Лучше создать обёртку и в C# использовать её.

AM>>>Обёртку можно сделать на чистом С, либо с помощью COM, либо C++/CLI.
А>>Каким образом через СОМ? Стандартные СОМ объекты, написанные на С++ спокойно работали используя Activator.CreateInstance, в данном случае постоянно выдает ошибку, не правильно определен тип.
AM>Создать COM класс и из него вызывать методы исходного С++ класса.
Можете прислать пример на С++ (для оболочки) как работать с полученной на класс ссылкой (как описать класс, как вызывать методы....)? В написании СОМ проблем нет.
AM>>>Пример для С++/CLI: http://msdn.microsoft.com/en-us/library/ms235281(v=vs.110).aspx
А>>Необходимо написать на C# импорт всех функций возвращаемого класса.
AM>Насколько я понимаю, это так или иначе в любом варианте придётся делать
Не правильно выразился, имел ввиду, что получится еще одна библиотека... прослойка.
mirag
Re[4]: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 11.06.13 06:15
Оценка:
Здравствуйте, AntoxaM, Вы писали:

Вопрос в дополнение, можно ли использовать unsafe-блоки, что бы не писать доп. библиотеку? И если да, то можно ли пример....

AM>>>Напрямую, в принципе можно, но крайне осторожно.

А>>Вопрос: В чем осторожность? У меня при вызовах метода всегда дает ошибку разрушения памяти.
А>>Я использовал и прямое присвоение и через Marshal.PtrToStructure использовав в качестве параметра класс.
А>>И через Marshal.GetDelegateForFunctionPointer (хотя в MSDN написано что этот метод нельзя применять при импорте из С++),
А>>и через Interface — результат то же — разрушение памяти. (не совпадают наверняка адреса методов в памяти.)
А>>Мне кажется необходимо при импорте PtrToSructure каким то образом упаковать (распаковать, поставить размер) импортируемого класса.

AM>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде. Поэтому не стал даже пробовать и посоветовать ничего не могу.


AM>>>Лучше создать обёртку и в C# использовать её.

AM>>>Обёртку можно сделать на чистом С, либо с помощью COM, либо C++/CLI.
А>>Каким образом через СОМ? Стандартные СОМ объекты, написанные на С++ спокойно работали используя Activator.CreateInstance, в данном случае постоянно выдает ошибку, не правильно определен тип.
AM>Создать COM класс и из него вызывать методы исходного С++ класса.
AM>>>Пример для С++/CLI: http://msdn.microsoft.com/en-us/library/ms235281(v=vs.110).aspx
А>>Необходимо написать на C# импорт всех функций возвращаемого класса.
AM>Насколько я понимаю, это так или иначе в любом варианте придётся делать
mirag
Re[4]: Работа со ссылкой на класс.
От: drol  
Дата: 11.06.13 10:21
Оценка:
Здравствуйте, AntoxaM, Вы писали:

AM>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде


Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.
Re[3]: Работа со ссылкой на класс.
От: drol  
Дата: 11.06.13 10:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Необходимо написать на C# импорт всех функций возвращаемого класса.


Для импорта, необходимо наличие соответствующего ему экспорта. Он в Вашей библиотеке есть ?
Re[4]: Работа со ссылкой на класс.
От: Аноним  
Дата: 13.06.13 05:56
Оценка:
Здравствуйте, drol, Вы писали:

D>Для импорта, необходимо наличие соответствующего ему экспорта. Он в Вашей библиотеке есть ?


Имелось ввиду не импорт функций из классической DLL (это все прекрасно работает через DllImport), а реализация функций возвращаемого класса. (см. первое сообщение).
Re[5]: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 13.06.13 05:59
Оценка:
Здравствуйте, drol, Вы писали:

AM>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде


D>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.


Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.
mirag
Re[5]: Работа со ссылкой на класс.
От: drol  
Дата: 15.06.13 14:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Имелось ввиду не импорт функций


Я прекрасно понимаю, что Вы имеете в виду. И посему ещё раз повторяю: если Вы хотите какой-то импорт, то сначала надо сделать соответствующий этому импорту экспорт.

Бо в общем случае понятие "функция-член класса" применимо лишь к исходному коду. Компилятор\линкер\оптимизатор могут эту Вашу функцию, например, тупо элиминировать, если она нигде в программе не вызывается... Или везде заинлайнить... Или ещё чего-нибудь...
Re[6]: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 18.06.13 10:06
Оценка:
Здравствуйте, drol, Вы писали:

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


А>>Имелось ввиду не импорт функций


D>Я прекрасно понимаю, что Вы имеете в виду. И посему ещё раз повторяю: если Вы хотите какой-то импорт, то сначала надо сделать соответствующий этому импорту экспорт.

Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта. В данном случае доступно только получения ссылки на класс. (Что собственно и сделано).

D>Бо в общем случае понятие "функция-член класса" применимо лишь к исходному коду. Компилятор\линкер\оптимизатор могут эту Вашу функцию, например, тупо элиминировать, если она нигде в программе не вызывается... Или везде заинлайнить... Или ещё чего-нибудь...
mirag
Re[7]: Работа со ссылкой на класс.
От: drol  
Дата: 18.06.13 13:27
Оценка: +1
Здравствуйте, mirag_ga, Вы писали:

_>Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта.


Ну так напишите для библиотеки обёртку. И экспортируйте обёртку.
Re[6]: Работа со ссылкой на класс.
От: icWasya  
Дата: 18.06.13 13:35
Оценка:
Здравствуйте, mirag_ga, Вы писали:

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


AM>>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде


D>>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.


_>Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.


Ну для начала, какие методы этого класса экспортирует DLL, как они выглядят в секции экспорта, и какие у них соглашения о вызовах.
Например приведите парочку.
Re[6]: Работа со ссылкой на класс.
От: AntoxaM  
Дата: 18.06.13 19:49
Оценка:
Здравствуйте, mirag_ga, Вы писали:

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


AM>>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде


D>>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.


_>Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.


вот ещё один пример как это сделать: http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class .
Вроде как методы описать, откуда что взять расписано.
Ну а так, покажите что написали, что компилятор говорит
Re[8]: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 27.06.13 11:31
Оценка:
Здравствуйте, drol, Вы писали:

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


_>>Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта.


D>Ну так напишите для библиотеки обёртку. И экспортируйте обёртку.

Я так думаю именно так и придется делать.
Надеялся есть другие варианты.
Спасибо за участие.
mirag
Re: Работа со ссылкой на класс.
От: mirag_ga Россия  
Дата: 27.06.13 11:32
Оценка:
Здравствуйте, mirag_ga, Вы писали:

_>Добрый день.

_>Библиотека (классическая, не СОМ) возвращает ссылку на класс:

_>long GetClassObject()

_>{
_>*pInterface= new CAddInNative;
_>return (long)*pInterface;
_>}

_>в программе на C# эту ссылку я получил присвоив типу IntPtr:


_>[DllImport("....dll", CharSet = CharSet.Auto, SetLastError = true)]

_>private static extern IntPtr GetClassObject();

_>Вопрос:

_>Как вызвать методы класса CAddinNative? Т.е. как описать этот полученный класс на C#?

_>Заранее благодарен за помощь.


Спасибо всем за участие.
mirag
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.