Dll на C++, пример использования на С#
От: oleg_dm  
Дата: 31.01.06 15:41
Оценка:
Есть 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# в принципе соотвествует примеру на С++ или где-то что то я упустил.

Спасибо, что дочитали до конца.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.