Matlab reading data using DLL and winsock2

3 次查看(过去 30 天)
Hi, I am trying to interface Matlab with a C code that I used to read data through UDP.
I am using the winsock2 library, and compiling the C code into a DLL file for it to be loaded into Matlab. My C code is working fine and reading the udp data as expected. But when I use the same code via'loadlibrary' function in Matlab, it just returns me all zeroes. The problem is definitely on the MATLAB side since I have already verified C code to be working and reading data properly. Does anyone have an idea of what I am doing wrong? My C code, header file and Matlab script are given below:
C code:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h> // Include for Sleep function
#include "udpfunc2.h"
#define BUFLEN 48
SOCKET s;
// Function to initialize UDP socket
int init_udp_socket() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
return 0;
}
// Function to create and bind UDP socket
int create_udp_socket() {
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
printf("Socket creation failed\n");
return -1;
}
return 0;
}
// Function to bind UDP socket to specified IP address and port
int bind_udp_socket(const char *ip_address, int port) {
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ip_address);
server.sin_port = htons(port);
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed\n");
return -1;
}
return 0;
}
// Function to set socket to non-blocking mode
int set_socket_nonblocking() {
unsigned long mode = 1; // 1 to enable non-blocking mode
if (ioctlsocket(s, FIONBIO, &mode) != 0) {
printf("Failed to set socket to non-blocking mode\n");
return -1;
}
return 0;
}
// Function to continuously read data through UDP as 12 single values (non-blocking)
void udp_read_continuous(float *data) {
struct sockaddr_in si_other;
int slen = sizeof(si_other);
int recv_len;
//zero out the memory buffer
memset(data,0,12 * sizeof(float));
recv_len = recvfrom(s, (char *)data, BUFLEN, 0, (struct sockaddr *)&si_other, &slen);
// Convert data from big-endian to host byte order
// Assuming each single value is a 32-bit float
for (int i = 0; i < 12; i++) {
unsigned int val;
memcpy(&val , &data[i], sizeof(float));
val = ntohl(val);
data[i] = *((float*)&val);
}
// Print received data
printf("Received data: ");
for (int i = 0; i < 12; i++) {
printf("%.6f ", data[i]);
}
printf("\n");
}
// Function to close UDP socket
void close_udp_socket() {
closesocket(s);
WSACleanup();
}
Header File:
#ifndef UDP_FUNC2_H
#define UDP_FUNC2_H
#include <winsock2.h>
#ifdef __cplusplus
extern "C" {
#endif
// Function prototypes
int init_udp_socket();
int create_udp_socket();
int bind_udp_socket(const char *ip_address, int port);
int set_socket_nonblocking();
void udp_read_continuous(float *data);
void close_udp_socket();
#ifdef __cplusplus
}
#endif
#endif // UDP_FUNC2_H
MATLAB Script
clc;
clear;
if libisloaded('udpfunc2')
unloadlibrary('udpfunc2')
end
loadlibrary('udpfunc2.dll', 'udpfunc2.h');
% Define UDP parameters
ip_address = '127.0.0.1'; % Local IP address
localPort = 44444; % Example port number
% Initialize UDP socket
status = calllib('udpfunc2', 'init_udp_socket');
if status == 0
disp('UDP socket initialized successfully');
else
disp('Failed to initialize UDP socket');
return;
end
% Open UDP socket
status = calllib('udpfunc2', 'create_udp_socket');
if status == -1
disp('Failed to Open UDP Socket');
end
% Bind UDP Socket to Local Port and IP address
status = calllib('udpfunc2', 'bind_udp_socket', ip_address, localPort);
if status == 0
disp('UDP socket binded successfully');
else
disp('Failed to bind socket');
return;
end
% Set Socket to Non-Blocking
status = calllib('udpfunc2', 'set_socket_nonblocking');
if status == 0
disp('UDP socket set to Non-Blocking successfully');
else
disp('Failed to set socket to Non-Blocking');
return;
end
% Create a MATLAB struct to hold the 12 single values
dataPacket = zeros(1, 12, 'single');
% Read continuous UDP data
while true
calllib('udpfunc2', 'udp_read_continuous', dataPacket);
fprintf('%.6f\n', dataPacket(12));
end
% Close UDP socket
calllib('udpfunc2', 'close_udp_socket');
disp('UDP socket closed');
% Unload the DLL
unloadlibrary('udpfunc2');

回答(1 个)

Hassaan
Hassaan 2024-5-17
编辑:Hassaan 2024-5-17
Adjust as per your need:
clc;
clear;
if libisloaded('udpfunc2')
unloadlibrary('udpfunc2')
end
loadlibrary('udpfunc2.dll', 'udpfunc2.h');
% Define UDP parameters
ip_address = '127.0.0.1'; % Local IP address
localPort = 44444; % Example port number
% Initialize UDP socket
status = calllib('udpfunc2', 'init_udp_socket');
if status == 0
disp('UDP socket initialized successfully');
else
disp('Failed to initialize UDP socket');
return;
end
% Open UDP socket
status = calllib('udpfunc2', 'create_udp_socket');
if status == -1
disp('Failed to open UDP socket');
return;
end
% Bind UDP Socket to Local Port and IP address
status = calllib('udpfunc2', 'bind_udp_socket', ip_address, localPort);
if status == 0
disp('UDP socket bound successfully');
else
disp('Failed to bind socket');
return;
end
% Set Socket to Non-Blocking
status = calllib('udpfunc2', 'set_socket_nonblocking');
if status == 0
disp('UDP socket set to Non-Blocking successfully');
else
disp('Failed to set socket to Non-Blocking');
return;
end
% Create a MATLAB struct to hold the 12 single values
dataPacket = libpointer('singlePtr', zeros(1, 12, 'single'));
% Read continuous UDP data
while true
calllib('udpfunc2', 'udp_read_continuous', dataPacket);
receivedData = get(dataPacket, 'Value');
fprintf('Received data: ');
fprintf('%.6f ', receivedData);
fprintf('\n');
pause(0.1); % Add a small delay to prevent busy-waiting
end
% Close UDP socket
calllib('udpfunc2', 'close_udp_socket');
disp('UDP socket closed');
% Unload the DLL
unloadlibrary('udpfunc2');
C Function: Ensure Proper Memory Handling
In your C function, make sure that the memory handling is correct. Since you mentioned the C code is working fine independently, there might be no need for changes here, but ensure that the data manipulation is consistent.
If the above changes do not resolve the issue, consider checking the following:
  1. Verify Data Alignment: Ensure that the data types and memory alignments are consistent between MATLAB and the C function.
  2. Error Checking: Add more error checking in your C code to verify that the data is being received correctly.
  3. Debugging: Use debugging statements to print out intermediate values and confirm that the data is being transferred as expected.

产品


版本

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by