Здравствуйте, oleg_dm, Вы писали:
_>Есть dll на C++.
_>Пример её использования (загрузку функций из dll пропустим)
_>_>void Allocate(char** pbuffer, unsigned long* psize)
_>{
_> *psize = *psize * 2;
_> *pbuffer = new char[*psize];
_>}
_>//----------------------------------------------------------------
_>void Deallocate(char* buffer)
_>{
_> delete[] buffer;
_>}
_>//----------------------------------------------------------------
_>int main(int argc, char* argv[])
_>{
_> SetAllocateFunction(Allocate);
_> SetDeallocateFunction(Deallocate);
_> std::ofstream fout;
_> char* data;
_> unsigned long size;
_> int client = 1, ret;
_> if(ret = CreateClient(client)){
_> std::cout << "\nerror ont create client, code: " << ret << '\n';
_> return 0;
_> }
_> SetClientIp(client, "192.168.253.10");
_> if(UpdateVersion(client)){
_> std::cout << "error: with code: ";
_> return 0;
_> }
_> if(GetImage(client, &data, &size, 1, 1.0, 0, 0)){
_> fout.open("full.jpg", std::ios_base::binary);
_> for(unsigned long i = 0; i < size; i++)
_> fout.put(data[i]);
_> fout.close();
_> }
_> DestroyClient(client);
_> return 0;
_>}
_>
_>Прототипы экспортируемых функций (extern "C" и прочее пропустим):
_>_>int CreateClient(int);
_>void DestroyClient(int);
_>int SetClientIp(int, const char*);
_>int GetImage(int number, char** pdata, unsigned long* size, int resoltion, float zoom, int dx, int dy);
_>int UpdateVersion(int);
_>void SetAllocateFunction(PTR_Allocate);
_>typedef void (*PTR_Allocate)(char**, unsigned long*);
_>
_>И тут пришла беда
партия приказала мне сделать такой же пример на С#, на котором сейчас только "Здраствуй мир" могу вывести в консоль.
_>Конечно кое-что набросал, а именно
_>_>using System;
_>using System.IO;
_>using System.Runtime.InteropServices;
_>namespace ExAV2000SDK
_>{
_> public delegate void PtrAllocate(ref byte[] buffer, ref ulong size);
_> class AV2000F
_> {
_> [DllImport( "AV2000SDK.dll", EntryPoint="CreateClient")]
_> public static extern int CreateClient(int number);
_> [DllImport( "AV2000SDK.dll", EntryPoint="DestroyClient")]
_> public static extern void DestroyClient(int number);
_> [DllImport( "AV2000SDK.dll", EntryPoint="SetClientIp")]
_> public static extern int SetClientIp(int number, string ip);
_> [DllImport( "AV2000SDK.dll", EntryPoint="UpdateVersion")]
_> public static extern int UpdateVersion(int number);
_> [DllImport( "AV2000SDK.dll", EntryPoint="GetImage")]
_> public static extern unsafe int GetImage(int number, byte** data, uint* size, int resolution, double zoom, int dx, int dy);
_> [DllImport( "AV2000SDK.dll", EntryPoint="SetAllocateFunction")]
_> public static extern void SetAllocateFunction(PtrAllocate pAllocate);
_> }
_> class Class1
_> {
_> public static void Allocate(ref byte[] buffer, ref ulong size)
_> {
_> size *= 2;
_> buffer = new byte[size];
_> }
_> [STAThread]
_> unsafe static void Main(string[] args)
_> {
_> PtrAllocate ptralloc = new PtrAllocate(Class1.Allocate);
_> AV2000F.SetAllocateFunction(ptralloc);
_> byte* data;
_> uint size;
_> int client = 1, ret;
_> ret = AV2000F.CreateClient(client);
_> if (ret != 0) { Console.Write("error on create client"); Console.WriteLine(); return; }
_> AV2000F.SetClientIp(client, "192.168.253.10");
_> ret = AV2000F.UpdateVersion(client);
_> if (ret == 0) { Console.Write("error on update version"); Console.WriteLine(); return; }
_> ret = AV2000F.GetImage(client, &data, &size, 1, 1.0, 0, 0);
_> if (ret == 0) { Console.Write("error on get image"); Console.WriteLine(); return; }
_> FileStream fstream = new FileStream("full.jpg", FileMode.Create);
_> for(uint i = 0; i < size; i++) fstream.WriteByte(data[i]);
_> AV2000F.DestroyClient(client);
_> }
_> }
_>}
_>
_>Сиысл AV2000F.SetAllocateFunction такой(на всякий случай): в функциях UpdateVersion и GetImage вызывается функция(есс-но при условии что выделенной памяти не хватает, ну и 1раз вызывается обязательно) указатель на которую устанавливает SetAllocateFunction
_>Выскакивает исключение System.NullReferenceException на вызове AV2000F.UpdateVersion.
_>Вопрос такой : набросок мой на C# в принципе соотвествует примеру на С++ или где-то что то я упустил.
_>Спасибо, что дочитали до конца.
1. делегат != указатель на ф-ию. тут нужно обвертку писать
2. в NET имхо аллокаторы не нужны, потому как памятью заправляет GC.
3. если напряг на C# писать — создай MC++ проект.