Здравствуйте, 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#?
_>Заранее благодарен за помощь.
Здравствуйте, 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# импорт всех функций возвращаемого класса.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, 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# импорт всех функций возвращаемого класса.
Насколько я понимаю, это так или иначе в любом варианте придётся делать
Здравствуйте, 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>Насколько я понимаю, это так или иначе в любом варианте придётся делать
Не правильно выразился, имел ввиду, что получится еще одна библиотека... прослойка.
Вопрос в дополнение, можно ли использовать 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>Насколько я понимаю, это так или иначе в любом варианте придётся делать
Здравствуйте, AntoxaM, Вы писали:
AM>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде
Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.
Здравствуйте, Аноним, Вы писали:
А>Необходимо написать на C# импорт всех функций возвращаемого класса.
Для импорта, необходимо наличие соответствующего ему экспорта. Он в Вашей библиотеке есть ?
Re[4]: Работа со ссылкой на класс.
От:
Аноним
Дата:
13.06.13 05:56
Оценка:
Здравствуйте, drol, Вы писали:
D>Для импорта, необходимо наличие соответствующего ему экспорта. Он в Вашей библиотеке есть ?
Имелось ввиду не импорт функций из классической DLL (это все прекрасно работает через DllImport), а реализация функций возвращаемого класса. (см. первое сообщение).
Здравствуйте, drol, Вы писали:
AM>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде
D>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.
Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.
Здравствуйте, Аноним, Вы писали:
А>Имелось ввиду не импорт функций
Я прекрасно понимаю, что Вы имеете в виду. И посему ещё раз повторяю: если Вы хотите какой-то импорт, то сначала надо сделать соответствующий этому импорту экспорт.
Бо в общем случае понятие "функция-член класса" применимо лишь к исходному коду. Компилятор\линкер\оптимизатор могут эту Вашу функцию, например, тупо элиминировать, если она нигде в программе не вызывается... Или везде заинлайнить... Или ещё чего-нибудь...
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>Имелось ввиду не импорт функций
D>Я прекрасно понимаю, что Вы имеете в виду. И посему ещё раз повторяю: если Вы хотите какой-то импорт, то сначала надо сделать соответствующий этому импорту экспорт.
Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта. В данном случае доступно только получения ссылки на класс. (Что собственно и сделано).
D>Бо в общем случае понятие "функция-член класса" применимо лишь к исходному коду. Компилятор\линкер\оптимизатор могут эту Вашу функцию, например, тупо элиминировать, если она нигде в программе не вызывается... Или везде заинлайнить... Или ещё чего-нибудь...
Здравствуйте, mirag_ga, Вы писали:
_>Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта.
Ну так напишите для библиотеки обёртку. И экспортируйте обёртку.
Здравствуйте, mirag_ga, Вы писали:
_>Здравствуйте, drol, Вы писали:
AM>>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде
D>>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.
_>Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.
Ну для начала, какие методы этого класса экспортирует DLL, как они выглядят в секции экспорта, и какие у них соглашения о вызовах.
Например приведите парочку.
Здравствуйте, mirag_ga, Вы писали:
_>Здравствуйте, drol, Вы писали:
AM>>>Мне показалось использовать магические @@QAEXH@Z, @@QAEXPAD@Z опасно, которые, подозреваю, ещё и поменяться могут при очередном билде
D>>Это всего лишь мнемоника описывающая название/тип/сигнатуру метода. Номер билда ничего не меняет.
_>Меня интересует как реализовать методы класса ссылку на который я получил и присвоил переменной с типом IntPtr? (Пробовал и через делегаты и описывать как интерфейс и через unsafe) все время возвращает ошибку разрушения памяти.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, mirag_ga, Вы писали:
_>>Исходная библиотека не доступна для перекомпелирования. Есть только ее полное описание. Если бы можно было бы изменить, можно было бы все функции написать для экспорта.
D>Ну так напишите для библиотеки обёртку. И экспортируйте обёртку.
Я так думаю именно так и придется делать.
Надеялся есть другие варианты.
Спасибо за участие.
Здравствуйте, 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#?
_>Заранее благодарен за помощь.