2016-10-03 16 views
0

私はC#を学んでいて、その経験があります。小さなプロジェクトでは、C#アプリケーションにC++のDLLを実装する必要があります。これは、ライセンスプレート認識sdkです。私はそれを初期化することができますので、このC + +コードを呼び出す作業です。しかし、私は文字列を含むC++コードから構造体を受け取るのに問題があります。私はたくさん試しましたが、ここでたくさん読んでいますが、うまく動作しません。構造体をC++のDLLからC#アプリケーションに変換する

[DllImport("D:\\processor.dll", EntryPoint = "StartALPR", CallingConvention = CallingConvention.Cdecl)] 
[return:MarshalAs(UnmanagedType.LPStruct)] 
public static extern TMyData StartALPR(TImageSource tImageSource); 

C#の構造体のTMyData:これは、C#側で

[StructLayout(LayoutKind.Sequential)] 

public struct TMyData 
{ 

    [MarshalAs(UnmanagedType.LPTStr)]   
    public string PlateString; 


    [MarshalAs(UnmanagedType.LPTStr)] 
    public string PlateXML; 


    [MarshalAs(UnmanagedType.LPTStr)] 
    public string LastError; 

}; 

そして、これは我々が分析する画像へのファイルパスの文字列が含まれているtImageSourceを送信するために呼び出すメソッドです。

alprResult = StartALPR(tImageSource);

ファイルが解析されているため、動作しています。私はVS2015の出力にプレートの文字列を見ることができます。 しかし、私は構造体 "alprResult"がTMydataで定義されていると期待していますが、メソッドの符号がpinvoke符号と互換性がないという例外があります。私が持っている唯一の情報は、C++でこのdll/codeを使用する方法の例です。これは、C++コードです:私はC#でこれを使用するにはどうすればよい

struct TMyData; 
    typedef TMyData *PMyData; 

     struct TMyData 
     { 
     /** 
     PlateString: Best license plate number of the plate group 
     */ 
    const char * PlateString;   
    /** 
    PlateXML: Plate group data in standard XML string 
    */ 
    const char * PlateXML;   
    /** 
    LastError: Laast config error ex: bad file extensions   ..     Default: empty 
    */ 
    const char * LastError;  

     }; 

TImageSource SImageSource; 
TMyData *pd; 

/* Set input image */ 
SImageSource.MyImageFile = AnsiString(CarImage).c_str(); 
Memo1->Lines->Clear(); 

/* Starting plate detect and recognition */ 
pd = StartALPR(&SImageSource); 

/* Standard XML result, the plate datas with numbers and positions */ 
Memo1->Lines->Add(pd->PlateXML); 

/* last error message */ 
Memo2->Lines->Add(pd->LastError); 

/* Best characters on plate */ 
Edit1->Text = pd->PlateString; 

これは、同じ例からC++構造体ですか? ありがとうございます。

答えて

0

私は最近、これと同様の問題を実際に解決しなければなりませんでした。私は単にデータをシリアライズして構造体にし、それをローカルzeromqソケットに渡しました。

// 
// Weather update server in C++ 
// Binds PUB socket to tcp://*:5556 
// Publishes random weather updates 
// 
// Olivier Chamoux <[email protected]> 
// 
#include <zmq.hpp> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#if (defined (WIN32)) 
#include <zhelpers.hpp> 
#endif 

#define within(num) (int) ((float) num * random()/(RAND_MAX + 1.0)) 

int main() { 

    // Prepare our context and publisher 
    zmq::context_t context (1); 
    zmq::socket_t publisher (context, ZMQ_PUB); 
    publisher.bind("tcp://*:5556"); 
    publisher.bind("ipc://weather.ipc");    // Not usable on Windows. 

    // Initialize random number generator 
    srandom ((unsigned) time (NULL)); 
    while (1) { 

     int zipcode, temperature, relhumidity; 

     // Get values that will fool the boss 
     zipcode  = within (100000); 
     temperature = within (215) - 80; 
     relhumidity = within (50) + 10; 

     // Send message to all subscribers 
     zmq::message_t message(20); 
     snprintf ((char *) message.data(), 20 , 
      "%05d %d %d", zipcode, temperature, relhumidity); 
     publisher.send(message); 

    } 
    return 0; 
} 

となりましクライアント

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 

using ZeroMQ; 

namespace Examples 
{ 
    static partial class Program 
    { 
     public static void WUClient(string[] args) 
     { 
      // 
      // Weather update client 
      // Connects SUB socket to tcp://127.0.0.1:5556 
      // Collects weather updates and finds avg temp in zipcode 
      // 
      // Author: metadings 
      // 

      if (args == null || args.Length < 2) 
      { 
       Console.WriteLine(); 
       Console.WriteLine("Usage: ./{0} WUClient [ZipCode] [Endpoint]", AppDomain.CurrentDomain.FriendlyName); 
       Console.WriteLine(); 
       Console.WriteLine(" ZipCode The zip code to subscribe. Default is 72622 Nürtingen"); 
       Console.WriteLine(" Endpoint Where WUClient should connect to."); 
       Console.WriteLine("    Default is tcp://127.0.0.1:5556"); 
       Console.WriteLine(); 
       if (args.Length < 1) 
        args = new string[] { "72622", "tcp://127.0.0.1:5556" }; 
       else 
        args = new string[] { args[0], "tcp://127.0.0.1:5556" }; 
      } 

      string endpoint = args[1]; 

      // Socket to talk to server 
      using (var context = new ZContext()) 
      using (var subscriber = new ZSocket(context, ZSocketType.SUB)) 
      { 
       string connect_to = args[1]; 
       Console.WriteLine("I: Connecting to {0}…", connect_to); 
       subscriber.Connect(connect_to); 

       /* foreach (IPAddress address in WUProxy_GetPublicIPs()) 
        { 
         var epgmAddress = string.Format("epgm://{0};239.192.1.1:8100", address); 
         Console.WriteLine("I: Connecting to {0}…", epgmAddress); 
         subscriber.Connect(epgmAddress); 
        } 
       } */ 

       // Subscribe to zipcode 
       string zipCode = args[0]; 
       Console.WriteLine("I: Subscribing to zip code {0}…", zipCode); 
       subscriber.Subscribe(zipCode); 

       // Process 10 updates 
       int i = 0; 
       long total_temperature = 0; 
       for (; i < 20; ++i) 
       { 
        using (var replyFrame = subscriber.ReceiveFrame()) 
        { 
         string reply = replyFrame.ReadString(); 

         Console.WriteLine(reply); 
         total_temperature += Convert.ToInt64(reply.Split(' ')[1]); 
        } 
       } 
       Console.WriteLine("Average temperature for zipcode '{0}' was {1}°", zipCode, (total_temperature/i)); 
      } 
     } 
    } 
} 
+0

私は@πάνταῥεῖ –

+0

ことをやったあなたにチャック・ノリスをありがとうございます。私は別の方法でそれを解決した、それはポインタを返していた。 – Denniss

関連する問題