Для нижестоящих пользователей : Этот ответ решает две проблемы: немедленную проблему соглашения о вызовах / атрибута MarhsalAs
и проблему, которую он вскоре найдет, где его параметр TTest
не будет работатьесли он примет мое предложение превратить TTest
в структуру.
Ваш нативный код запрашивает void*
, что в C # - IntPtr
.Сначала вы должны определить TTest
как структуру, а не класс.Во-вторых, вы должны изменить объявление Foo
на:
[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(IntPtr lplf);
И в-третьих, вы должны закрепить TTest
с помощью ключевого слова fixed
и передать его указатель на Foo
.Если вы используете класс, вы можете использовать Marhsal.StructureToPtr
, чтобы получить IntPtr
от вашего TTest
.
Это обеспечивает одинаковую функциональность с обеих сторон, где можно передать указатель на любой типin. Вы также можете записывать перегрузки со всеми типами классов, которые вы хотите использовать, поскольку все они равны void*
на нативной стороне.Со структурой ваши параметры будут дополнены ref
.
. Меня интересует, почему ваш нативный код требует void*
вместо TTest*
, когда первое, что вы делаете внеуправляемый код приведен к TTest*
.Если вы переключили параметр на TTest*
, то предоставление идентичных функций станет проще.Ваша декларация стала бы:
[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(ref TTest lplf);
И вы бы назвали функцию как Program.Foo(ref Test);
Если вы используете класс, ref
не требуется, так как классы являются справочнымитипы.