Re: Dll на C++, пример использования на С#
От: dimchick Украина  
Дата: 31.01.06 15:58
Оценка:
Здравствуйте, 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++ проект.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.