2010-03-08 3 views
1

У меня есть определение функции в моем VC++ Win32 DLLнарушение C++ доступа при вызове функции DLL

DEMO2_API void ProcessData(char* i_buff, unsigned short i_len, char* o_buf, 
unsigned *o_len, unsigned short *errorCode) 
{ 
    __describe (i_buff,&i_len,o_buf,o_len,errorCode); 
} 

Эта функция DLL вызывается с помощью C# приложения. При вызове генерируется исключение нарушения доступа.

После повторного поиска я нашел причину моей проблемы.

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/6e843243-baf4-4eb1-8a20-c691ad47762c

Но не мог понять, что именно они doinng в примере кода. Может кто-нибудь объяснить это мне?

И что будет P/Invoke подписи в C# после внешнего выделения памяти?

+0

Вы можете сделать свою C++ DLL в C++/CLI-управляемую сборку? C++/CLI понимает как .NET arrays (cli :: array ), так и управление собственной памятью, что делает эту задачу очень простой. –

+0

но как я могу это сделать? .. какой-нибудь пример ??? – Manjoor

ответ

0

Я изменил проходящий режим O_len к из вместо исх и она работает.

Thnaks каждый за хорошие ответы и комментарии. Я надеюсь, что это было бы полезно для других членов сообщества (плюс те, что искали) ...

0

В C# используется IntPtr для представления выделенной извне памяти. Указатели и ссылки C# могут использоваться только с памятью, предоставляемой сборщиком мусора.

Класс System.InteropServices.Marshal предоставляет некоторые методы взаимодействия с областями памяти, представленными IntPtr, конечно, они не являются типичными.

Но я ничего не вижу в вашей функции, которая могла бы вернуть указатель на выделенную память. Вам понадобится аргумент с двумя указателями или возвращаемое значение указателя, и у вас их нет.

EDIT, чтобы добавить пример по запросу:

// this doesn't work right 
void external_alloc_and_fill(int n, int* result) 
{ 
    result = new int[n]; 
    while (n-- > 0) { result[n] = n; } 
} 

extern external_alloc_and_fill(int n, int* result) 
int a = 5; 
fixed (int* p = &a) { 
    external_alloc_and_fill(17, p); 
    // p still points to a, a is still 5 
} 

лучше:

// works fine 
void external_alloc_and_fill2(int n, int** presult) 
{ 
    int* result = *presult = new int[n]; 
    while (n-- > 0) { result[n] = n; } 
} 

extern external_alloc_and_fill2(int n, ref IntPtr result) 
int a 5; 
IntPtr p = &a; 
external_alloc_and_fill2(17, ref p); 
// a is still 5 but p is now pointing to the memory created by 'new' 
// you'll have to use Marshal.Copy to read it though 
+0

@Ben Voigt Третий параметр * o_buf будет возвращен в мое приложение. и мне нужно это как массив байтов – Manjoor

+0

@Manjoor: либо вызывающий выделяет пространство, либо передает указатель на него, либо вызывающий выделяет пространство и должен где-то хранить указатель, т. е. указатель на указатель. Нет способа, чтобы указатель, переданный по значению (например, ваш o_buf), мог использоваться для возврата буфера, выделенного внутри вызываемого абонента. –

+0

hmmmm. Можете ли вы показать мне пример из 4 строк? – Manjoor