1

C# プラットフォームで使用する C++ DLL を作成しましたが、C# の "printf" メッセージをテキスト ボックスに出力する方法がまったくわかりません。

これは、DLL ファイルのコードです。

#include "stdafx.h"
#define HAVE_REMOTE
#define MAX_BUF_SIZE 1024
#define snprintf _snprintf
#define ETH_ALEN 6
#define IP_ALEN 4
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define DllExport   __declspec( dllexport )

#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <pcap.h>
#include <iostream>

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Ws2_32.lib")


// A sample of the select() return value
DllExport int recvfromTimeOutUDP(SOCKET socket, long sec, long usec)
{
    // Setup timeval variable
    struct timeval timeout;
    struct fd_set fds;

    timeout.tv_sec = sec;
    timeout.tv_usec = usec;
    // Setup fd_set structure
    FD_ZERO(&fds);
    FD_SET(socket, &fds);
    // Return value:
    // -1: error occurred
    // 0: timed out
    // > 0: data ready to be read
    return select(0, &fds, 0, 0, &timeout);
}


extern "C" DllExport int ReceiverInformation(char* message, int length)
{
     WSADATA            wsaData;
     SOCKET             ReceivingSocket;
     SOCKADDR_IN        ReceiverAddr;
     int                Port = 5150;
     char           ReceiveBuf[6000];
     int                BufLength = 6000;
     SOCKADDR_IN        SenderAddr;
     int                SenderAddrSize = sizeof(SenderAddr);
     int                ByteReceived = 5, SelectTiming, ErrorCode;
     char ch = 'Y';
     std::string output;


   // Initialize Winsock version 2.2
   if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
   {
        output = "Server: WSAStartup failed with error " + WSAGetLastError();
        output += "\n";
   }
   else   
       output += "Server: The Winsock DLL status is "; 
       output += wsaData.szSystemStatus;
       output +="\n";

     // Create a new socket to receive datagrams on.
     ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

     if (ReceivingSocket == INVALID_SOCKET)
     {
          output += "Server: Error at socket(): " + WSAGetLastError();
          output += "\n";
          // Clean up
          WSACleanup();
          // Exit with error
          return -1;
     }
     else
          output += "Server: socket() is OK!\n";

     // Set up a SOCKADDR_IN structure that will tell bind that we
     // want to receive datagrams from all interfaces using port 5150.

     // The IPv4 family
     ReceiverAddr.sin_family = AF_INET;
     // Port no. 5150
     ReceiverAddr.sin_port = htons(Port);
     // From all interface (0.0.0.0)
     ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

   // Associate the address information with the socket using bind.
   // At this point you can receive datagrams on your bound socket.
   if (bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)) == SOCKET_ERROR)
   {
        output += "Server: bind() failed! Error: "+ WSAGetLastError();
        output += "\n";
        // Close the socket
        closesocket(ReceivingSocket);
        // Do the clean up
        WSACleanup();
        // and exit with error
        return -1;
     }
     else
          output += "Server: bind() is OK!\n";

   // Some info on the receiver side...
   getsockname(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr));

   output += "Server: Receiving IP(s) used: "; 
   output += inet_ntoa(ReceiverAddr.sin_addr);
   output += "\n";
   output += "Server: Receiving port used: %d\n" + htons(ReceiverAddr.sin_port);
   output += "Server: I\'m ready to receive a datagram...\n";

   SelectTiming = recvfromTimeOutUDP(ReceivingSocket, 100, 0);

   switch (SelectTiming)
        {
             case 0:
                 // Timed out, do whatever you want to handle this situation
                 output += "Server: Timeout while waiting for client!...\n";
                 break;
             case -1:
                 // Error occurred, maybe we should display an error message?
                // Need more tweaking here and the recvfromTimeOutUDP()...
                 output += "Server: Some error encountered with code number: %ld\n" + WSAGetLastError();
                 break;
             default:
                 {
                      while (1)


                      {
                           // Call recvfrom() to get it then display the received data...
                           ByteReceived = recvfrom(ReceivingSocket, ReceiveBuf, BufLength,
                                                    0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
                           if ( ByteReceived > 0 )
                           {
                               output += "\n\nServer: Total Bytes received: " + ByteReceived;
                               output += "\n";
                               output += "Server: The data is "; 
                               output += ReceiveBuf;
                               output += "\n";
                           }
                           else if ( ByteReceived <= 0 ){
                                output += "Server: Connection closed with error code: " + WSAGetLastError();
                                output += "\n";
                           }
                           else
                                output += "Server: recvfrom() failed with error code: " + WSAGetLastError();

                           // Some info on the sender side
                           getpeername(ReceivingSocket, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
                           output += "Server: Sending IP used: ";
                           output += inet_ntoa(SenderAddr.sin_addr);
                           output += "\n";
                           output += "Server: Sending port used: "+ htons(SenderAddr.sin_port);
                           output += "\n";
                      }
                 }
   }



   // When your application is finished receiving datagrams close the socket.
   output += "Server: Finished receiving. Closing the listening socket...\n";
   if (closesocket(ReceivingSocket) != 0){
        output += "Server: closesocket() failed! Error code: " + WSAGetLastError();
        output += "\n";
   }
   else
        output += "Server: closesocket() is OK...\n";

   // When your application is finished call WSACleanup.
   output += "Server: Cleaning up...\n";
   if(WSACleanup() != 0){
        output += "Server: WSACleanup() failed! Error code: " + WSAGetLastError();
        output += "\n";
   }
   else
        output += "Server: WSACleanup() is OK\n";
   output.c_str();
   // Back to the system
   // system("PAUSE");
   return 0;
}

これは、この DLL ファイルを呼び出すプログラムのコードです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace GUI_ServerReceiver
{
    public partial class Form1 : Form
    {
        [DllImport(@"C:\Users\Documents\Server_Receiver Solution DLL\Debug\Server_Receiver.dll", EntryPoint = "DllMain")]
        private static extern int ReceiverInformation(StringBuilder sb, int capacity);

        public Form1()
        {
            InitializeComponent();
            var sb = new StringBuilder(1024);
            ReceiverInformation(sb, sb.Capacity);
            textBox1.Text = sb.ToString();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Closes this application
            this.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }

}

4

1 に答える 1

0

c++ dll を c# プロジェクトにバインドします (呼び出す関数は「externed」にする必要があります)。たとえば、char* または std::string を返す dll に記述した印刷関数を呼び出してから、割り当てます。以前に作成した Textbox の "Text" プロパティに追加します。

于 2012-05-30T08:22:16.070 に答える