ipref3 dll for windows

1

I try to build ipref3.dll for windows

I found How to compile iperf3 for Windows

Built it but i got only iperf3.exe and libiperf.a

I found, how create dll manual

gcc -s -shared -o iperf3.dll units.o timer.o tcp_window_size.o tcp_info.o net.o iperf_util.o iperf_sctp.o iperf_udp.o iperf_tcp.o iperf_server_api.o iperf_locale.o iperf_client_api.o iperf_error.o iperf_api.o cjson.o -Wl,--enable-auto-import,--export-all-symbols,--subsystem,windows

after i found how need to initialize

HMODULE h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
init();

Now i can load dll and make initialization but when i start test iperf_run_client application is crashed

Unhandled exception at 0x611537C0 (cygwin1.dll) in iprerf-server.exe: 0xC0000005: Access violation reading location 0x00740000.

How can solve this problem?

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
//#include <unistd.h>
#include <string.h>
//#include <sysexits.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include "iperf_api.h"

#ifdef WIN64
#pragma comment(lib, "iperf3_64.lib")
#else
#pragma comment(lib, "iperf3.lib")
#endif

#pragma comment(lib, "ws2_32.lib")


typedef void *register_frame();
typedef int *hello_f();

typedef int(*PFN_HELLO)();
typedef void(*PFN_CYGWIN_DLL_INIT)();

#pragma pack(push, 1) 

int main(int argc, char** argv)
{
    WSADATA wsaData;
    int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (wsaErr != 0) {
        printf("WSAStartup failed with error: %d\n", wsaErr);
        return 1;
    }

    //PFN_HELLO fnHello;
    HMODULE /*hLib, */h = LoadLibrary(TEXT("cygwin1.dll"));
    PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
    init();

    char* argv0;
    char* host;
    int port;
    struct iperf_test *test;

    argv0 = strrchr(argv[0], '/');
    if (argv0 != (char*)0)
        ++argv0;
    else
        argv0 = argv[0];

    if (argc != 3) {
        fprintf(stderr, "usage: %s [host] [port]\n", argv0);
        exit(EXIT_FAILURE);
    }
    host = argv[1];
    port = atoi(argv[2]);

    test = iperf_new_test();
    if (test == NULL) {
        fprintf(stderr, "%s: failed to create test\n", argv0);
        exit(EXIT_FAILURE);
    }
    iperf_defaults(test);
    iperf_set_verbose(test, 1);

    iperf_set_test_role(test, 'c');
    iperf_set_test_server_hostname(test, host);
    iperf_set_test_server_port(test, port);
    /* iperf_set_test_reverse( test, 1 ); */
    iperf_set_test_omit(test, 3);
    iperf_set_test_duration(test, 5);
    iperf_set_test_reporter_interval(test, 1);
    iperf_set_test_stats_interval(test, 1);
    /* iperf_set_test_json_output( test, 1 ); */

    if (iperf_run_client(test) < 0) {
        fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
        exit(EXIT_FAILURE);
    }

    if (iperf_get_test_json_output_string(test)) {
        fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
            strlen(iperf_get_test_json_output_string(test)));
    }

    iperf_free_test(test);
    exit(EXIT_SUCCESS);

}
windows
dll
cygwin

2 Answers

0

The reason why the shared lib is not built is:

libtool: warning: undefined symbols not allowed in x86_64-unknown-cygwin 
shared libraries; building static only

the easy way to bypass it, in a clean build is to use:

$ make libiperf_la_LIBADD="-no-undefined"

The build will include the shared libray and the import library

$ find . -name "*dll*"
./src/.libs/cygiperf-0.dll
./src/.libs/libiperf.dll.a

For what I see to make a build on cygwin is also needed to remove a definition in src/iperf_config.h after running configure

/* #define HAVE_SETPROCESSAFFINITYMASK 1 */

PS #1: iperf-2.0.5-1 is available as cygwin package
PS #2: your code is Windows-like while Cygwin is a Unix-like system, you can not mix them

answered on Stack Overflow Aug 8, 2018 by matzeri
0

I found solution

1) It need to create addition dll: my_crt0.dll

#include <sys/cygwin.h>
#include <stdlib.h>

typedef int (*MainFunc) (int argc, char *argv[], char **env);

void my_crt0 (MainFunc f)
{
    cygwin_crt0(f);
}
gcc -c my_crt0.c
gcc -o my_crt0.dll my_crt0.o -s -shared -Wl,--subsystem,windows,--enable-auto-import,--export-all-symbols,--out-implib,my_crt0.lib

2) Modify main code

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
#include <string.h>

#include "iperf_api.h"

#pragma comment(lib, "iperf3.lib")
#pragma comment(lib, "ws2_32.lib")

typedef int(*MainFunc) (int argc, char *argv[], char **env);
typedef void(*my_crt0)(MainFunc f);

int main2(int argc, char** argv, char **env)
{
    char* argv0;
    char* host;
    int port;
    struct iperf_test *test;

    host = (char*)"127.0.0.1";
    port = 4000; 

    test = iperf_new_test();
    if (test == NULL) {
        exit(EXIT_FAILURE);
    }

    iperf_defaults(test);
    iperf_set_verbose(test, 1);

    iperf_set_test_role(test, 'c');
    iperf_set_test_server_hostname(test, host);
    iperf_set_test_server_port(test, port);
    /* iperf_set_test_reverse( test, 1 ); */
    iperf_set_test_omit(test, 3);
    iperf_set_test_duration(test, 5);
    iperf_set_test_reporter_interval(test, 1);
    iperf_set_test_stats_interval(test, 1);
    /* iperf_set_test_json_output( test, 1 ); */

    iperf_strerror(0);

    if (iperf_run_client(test) < 0) {
        fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
        exit(EXIT_FAILURE);
    }

    if (iperf_get_test_json_output_string(test)) {
        fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
            strlen(iperf_get_test_json_output_string(test)));
    }

    iperf_free_test(test);
    exit(EXIT_SUCCESS);

    return 1;
}

int main(int argc, char** argv)
{
    WSADATA wsaData;
    int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (wsaErr != 0) {
        printf("WSAStartup failed with error: %d\n", wsaErr);
        return 1;
    }

    {
        HMODULE /*hLib, */h = LoadLibrary(TEXT("my_crt0.dll"));
        my_crt0 init = (my_crt0)GetProcAddress(h, "my_crt0");
        init(main2);
    }

    exit(EXIT_SUCCESS);
}

Now it compiled and worked to VS 2015

answered on Stack Overflow Aug 13, 2018 by Иуфк СНН

User contributions licensed under CC BY-SA 3.0