khoih-prog / WebSockets2_Generic

A WebSocket Server and Client library for Arduino, based on RFC6455, for writing modern Websockets applications. Now support ESP8266, ESP32 (including ESP32-S2 Saola, AI-Thinker ESP-12K, WT32_ETH01, etc.), nRF52, SAMD21, SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, Teensy, RP2040-based, etc. boards, with WiFiNINA, Teensy 4.1 NativeEthernet/QNEthernet, Ethernet W5x00 / ENC28J60 / LAN8742A / LAN8720, ESP8266 / ESP32-AT modules/shields, as well as SINRIC / Alexa / Google Home
GNU General Public License v3.0
81 stars 30 forks source link

multiple definition of `websockets2_generic::WebsocketsServer::~WebsocketsServer()' in websocket2_generic library #3

Closed pchan1401-ICIL closed 3 years ago

pchan1401-ICIL commented 3 years ago

HI.

I’m using ‘adafruit feather m0’ board with w5500 and I succeed to run example code “SAMD-Ethernet-Client”. Also, I communicate server using websocket2_generic library. Then I want to separate code into two files.

While I was trying to make separate WebSocket header file using websockets2_generic library, I face weird error. I try to figure out it, but It was very complicated with my codes. Thus, I remove all of my code except necessary things such as “#define” and “#include”.

I have four files which is

SAMD-Ethernet-Client.ino EthernetWebSocketsClient.h EthernetWebSocketsClient.cpp defines.h

As the file name, I use the example code. defines.h is almost same with example code. I just remove unnecessary global values. Other files are same below.

SAMD-Ethernet-Client.ino

#include "EthernetWebSocketsClient.h"

void setup()
{}

void loop()
{}

EthernetWebSocketsClient.h

#ifndef EWC_H
#define EWC_H

#include "defines.h"
#include <WebSockets2_Generic.h>

#endif

EthernetWebSocketsClient.cpp

#include "EthernetWebSocketsClient.h"

As I mentioned before, I remove all the code. Those are the full code. When compiling, it shows error like below

c:/users/chanyoung/appdata/local/arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\CHANYO~1\AppData\Local\Temp\arduino_build_4918\sketch\SAMD-Ethernet-Client.ino.cpp.o: in function std::function<void (websockets2_generic::WebsocketsClient&, websockets2_generic::WebsocketsMessage)>::operator bool() const': C:\Arduino\libraries\WebSockets2_Generic-master\src/Tiny_Websockets_Generic/internals/wscrypto/sha1.hpp:73: multiple definition ofwebsockets2_generic::WebsocketsServer::~WebsocketsServer()'; C:\Users\CHANYO~1\AppData\Local\Temp\arduino_build_4918\sketch\EthernetWebSocketsClient.cpp.o:C:\Arduino\libraries\WebSockets2_Generic-master\src/WebSockets2_Generic_Server.hpp:182: first defined here c:/users/chanyoung/appdata/local/arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\CHANYO~1\AppData\Local\Temp\arduino_build_4918\sketch\SAMD-Ethernet-Client.ino.cpp.o: in function std::function<void (websockets2_generic::WebsocketsClient&, websockets2_generic::WebsocketsMessage)>::operator bool() const': C:\Arduino\libraries\WebSockets2_Generic-master\src/Tiny_Websockets_Generic/internals/wscrypto/sha1.hpp:73: multiple definition ofwebsockets2_generic::WebsocketsServer::~WebsocketsServer()'; C:\Users\CHANYO~1\AppData\Local\Temp\arduino_build_4918\sketch\EthernetWebSocketsClient.cpp.o:C:\Arduino\libraries\WebSockets2_Generic-master\src/WebSockets2_Generic_Server.hpp:182: first defined here c:/users/chanyoung/appdata/local/arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\CHANYO~1\AppData\Local\Temp\arduino_build_4918\sketch\SAMD-Ethernet-Client.ino.cpp.o: in function `websockets2_generic::WebsocketsServer::~WebsocketsServer()':

It shows multiple definition.

I change codes in EthernetWebSocketsClient.h, SAMD-Ethernet-Client.ino.

SAMD-Ethernet-Client.ino

#ifndef EWC_H
#define EWC_H

#endif

SAMD-Ethernet-Client.ino

#include "defines.h"
#include <WebSockets2_Generic.h>

#include "EthernetWebSocketsClient.h"

void setup()
{}

void loop()
{}

I just change the location of

#include "defines.h"
#include <WebSockets2_Generic.h>

Then, I succeed to compile and linking.

I want to implement websocket functions in EthernetWebSocketsClient.cpp file. Thus, EthernetWebSocketsClient.h include websocket2_generic library.

How can I include websocket2_generic library in EthernetWebSocketsClient.h file.

khoih-prog commented 3 years ago

@pchan1401-ICIL

Thanks for using the library. The problems you experienced happened because the complicated feature of the libraries.

You can use either solutions as follows:

1. Better implementation

SAMD-Ethernet-Client.ino EthernetWebSocketsClient.h EthernetWebSocketsClient_Impl.h defines.h

SAMD-Ethernet-Client.ino

#include "defines.h"

#include <WebSockets2_Generic.h>

#include "EthernetWebSocketsClient.h"

using namespace websockets2_generic;

void setup()
{}

void loop()
{}

EthernetWebSocketsClient.h

#ifndef EWC_H
#define EWC_H

#include "EthernetWebSocketsClient_Impl.h"    

#endif

EthernetWebSocketsClient_Impl.h

#ifndef EWC_Impl_H
#define EWC_Impl_H

#endif

2. Another implementation

SAMD-Ethernet-Client.ino EthernetWebSocketsClient.h EthernetWebSocketsClient.cpp defines.h

SAMD-Ethernet-Client.ino

#include "defines.h"

#include <WebSockets2_Generic.h>

#include "EthernetWebSocketsClient.h"

using namespace websockets2_generic;

void setup()
{}

void loop()
{}

EthernetWebSocketsClient.h

#ifndef EWC_H
#define EWC_H

#endif

EthernetWebSocketsClient.cpp

#include "EthernetWebSocketsClient.h"

If you are OK with any implementation, please post the result for other people to follow. It's complicated to explain all, it's better for you to research why if OK.

khoih-prog commented 3 years ago

This is the terminal output when running the same example on SAMD21 SeeedStudio XIAO Mo


Starting WebSockets2_Generic SAMD-Ethernet-Client on SEEED_XIAO_M0
Ethernet using W5x00 and Ethernet Library
[SETUP] BOOT WAIT 2
[SETUP] BOOT WAIT 1
_pinCS = 0
W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 1
W5100::init: W5500, SSIZE =4096
WebSockets Client IP address: 192.168.2.126
Connecting to WebSockets Server @192.168.2.81
[WS] WebsocketsClient::generateHandshake: base64Authorization = 
[WS] WebsocketsClient::generateHandshake: handshake = GET / HTTP/1.1
Host: 192.168.2.81
Sec-WebSocket-Key: MDEyMzQ1Njc4OWFiY2RlZg==
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
User-Agent: TinyWebsockets Client
Authorization: Basic 
Origin: https://github.com/khoih-prog/Websockets2_Generic

[WS] WebsocketsClient::connect: base64Authorization = 
[WS] WebsocketsClient::doestStartsWith: str = HTTP/1.1 101 Switching Protocols

[WS] WebsocketsClient::doestStartsWith: prefix = HTTP/1.1 101
[WS] WebsocketsClient::generateHandshake: key = Connection
[WS] WebsocketsClient::generateHandshake: value = Upgrade
[WS] WebsocketsClient::generateHandshake: key = Upgrade
[WS] WebsocketsClient::generateHandshake: value = websocket
[WS] WebsocketsClient::generateHandshake: key = Sec-WebSocket-Version
[WS] WebsocketsClient::generateHandshake: value = 13
[WS] WebsocketsClient::generateHandshake: key = Sec-WebSocket-Accept
[WS] WebsocketsClient::generateHandshake: value = BACScCJPNqyz+UBoqMH89VmURoA=
Connnection Opened
Connected!
Got Message: Echo: Hello to Server from SEEED_XIAO_M0
Connnection Closed
pchan1401-ICIL commented 3 years ago

Thank you for offering nice library. but your answer is slightly way off with my expection.

I'm using folder named SAMD-Ethernet-Client In this folder there are four files.

SAMD-Ethernet-Client.ino EthernetWebSocketsClient.h EthernetWebSocketsClient.cpp defines.h

I want to use library in EthernetWebSocketsClient.h not SAMD-Ethernet-Client.ino file.

Thus, "#include " should in EthernetWebSocketsClient.h

Putting "#include " into .ino file is successful. Also, I already run the examlpe code with my board. In addition, I succed to connect websocket server.

However, I want to make saperate file EthernetWebSocketsClient.h which using websocket library for code management.

For more easy explanation. Here is an example.

EthernetWebSocketsClient.h

#ifndef EWC_H
#define EWC_H

#include "defines.h"
#include <WebSockets2_Generic.h>

using namespace websockets2_generic;

class EWCTest
{
 public :
  void init();
 private :
  WebsocketsClient client;
};

#endif

Thank you for your reply.

khoih-prog commented 3 years ago

You can use this solution as follows:


SAMD-Ethernet-Client.ino EthernetWebSocketsClient.h EthernetWebSocketsClient_Impl.h defines.h


SAMD-Ethernet-Client.ino

#include "EthernetWebSocketsClient.h"

using namespace websockets2_generic;

void setup()
{}

void loop()
{}

EthernetWebSocketsClient.h

#ifndef EWC_H
#define EWC_H

#include "defines.h"
#include <WebSockets2_Generic.h>

using namespace websockets2_generic;

class EWCTest
{
 public :
  void init();
 private :
  WebsocketsClient client;
};

#include "EthernetWebSocketsClient_Impl.h"

#endif

EthernetWebSocketsClient_Impl.h

#ifndef EWC_Impl_H
#define EWC_Impl_H

#endif

pchan1401-ICIL commented 3 years ago

It works

Thaks a lot.

But what is the reason it makes error with ".cpp" file?

khoih-prog commented 3 years ago

That's left for you to research and investigate.

Thanks for confirming the solution.

pchan1401-ICIL commented 3 years ago

Thank you for your reply