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)
{
}
}
}