title: How to use Shared Library in PyBind11
body: <p>I am trying to use PyBind11 to create a C++ Wrapper to access my USB device on Ubuntu 22.04. I have working c++ program that does this .</p>
  <pre><code>#include &lt;iostream&gt;
  #include &quot;FUTEK_USB_DLL.h&quot;
  #include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;ctime&gt;
  #include &lt;ratio&gt;
  #include &lt;chrono&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fstream&gt;
  #include &lt;cmath&gt;
  
  using namespace std;
  int main()
  {
      _FUTEK_USB_DLL::FUTEK_USB_DLL dll;
  
      PVOID deviceHandle ;
      BYTE channelNumber = 0;
  
      string sn = dll.Get_Device_Serial_Number(0);
      char *serialNumber = new char[sn.length() + 1];
      strcpy(serialNumber, sn.c_str());
      dll.Open_Device_Connection(serialNumber);
      deviceHandle = dll.DeviceHandle;
  
      string boardType = dll.Get_Type_of_Board(deviceHandle);
      string firmVersion = dll.Get_Firmware_Version(deviceHandle);
      string samplingRate = dll.Get_ADC_Sampling_Rate(deviceHandle, channelNumber);
  
  
      double offsetValue = stod(dll.Get_Offset_Value(deviceHandle, channelNumber));
      double fullScaleLoad = stod(dll.Get_Fullscale_Load(deviceHandle, channelNumber));
      double offsetLoad = stod(dll.Get_Offset_Load(deviceHandle, channelNumber));
      double fullScaleValue = stod(dll.Get_Fullscale_Value(deviceHandle, channelNumber));
      double decimalPoint = stod(dll.Get_Decimal_Point(deviceHandle, channelNumber));
  
      cout &lt;&lt; &quot;Get_Offset_Value: &quot; &lt;&lt; offsetValue &lt;&lt; endl;
      cout &lt;&lt; &quot;Get_Fullscale_Load: &quot; &lt;&lt; fullScaleLoad &lt;&lt; endl;
      cout &lt;&lt; &quot;Get_Offset_Load: &quot; &lt;&lt; offsetLoad &lt;&lt; endl;
      cout &lt;&lt; &quot;Get_Fullscale_Value: &quot; &lt;&lt; fullScaleValue &lt;&lt; endl;
      cout &lt;&lt; &quot;Get_Decimal_Point: &quot; &lt;&lt; decimalPoint &lt;&lt; endl;
  
      while(true)
      {
          double normalDataRequest = stod(dll.Normal_Data_Request(deviceHandle, channelNumber));
          //cout &lt;&lt; &quot;Normal_Data_Request: &quot; &lt;&lt; normalDataRequest &lt;&lt; endl;
  
          float torque = (normalDataRequest - offsetValue)*((fullScaleLoad - offsetLoad)/(fullScaleValue-offsetValue)) / pow(10, decimalPoint);
  
          cout &lt;&lt; &quot;torque: &quot; &lt;&lt; torque &lt;&lt; endl;
          usleep((unsigned int)500000);
      }
      dll.Close_Device_Connection(serialNumber);
  
  }
  </code></pre>
  <p>This code uses two external shared libraries that I link when compiling.</p>
  <pre><code>all: main.cpp
          g++ -D _GLIBCXX_USE_CXX11_ABI=0 -std=c++11 -Wall  main.cpp -o main -lFUTEK_USB-x86_64 -lftd2xx 
  
  </code></pre>
  <p>I am now trying to use PyBind11 to be able to call this code from Python. I am new to PyBind11, but I did get the &quot;hello world&quot; example to compile and work from being called from python. My issue is I am not sure how to link these two dependencies (FUTEK_USB and lftd2xx) in my module using CMake. Here is my CMakeLists.txt</p>
  <pre><code>cmake_minimum_required(VERSION 3.4)
  project(pybind_test)
  
  find_library(futekLib FUTEK_USB-x86_64)
  
  if (${futekLib} STREQUAL futekLib-NOTFOUND)
      message(FATAL_ERROR &quot;No FutekLib, sad day&quot;)
  else()
      message(STATUS &quot;futeklib Found! as ${futekLib}&quot;)
  endif()
  
  find_library(ftd2xxLib ftd2xx)
  
  if (${ftd2xxLib} STREQUAL ftd2xxLib-NOTFOUND)
      message(FATAL_ERROR &quot;No ftd2xxLib, sad day&quot;)
  else()
      message(STATUS &quot;ftd2xxLib Found! as ${ftd2xxLib}&quot;)
  endif()
  
  
  
  add_subdirectory(pybind11)
  include_directories(thirdparty)
  pybind11_add_module(bind_test main.cpp)
  target_link_libraries(bind_test PUBLIC ${futekLib} ${ftd2xxLib})
  
  </code></pre>
  <p>By adding those <code>message</code> statements to my CMakeLists.txt I can confirm that it does find those two libraries. When i build this python module and then try to import it, I keep getting this undefined reference</p>
  <pre><code>&lt;ipython-input-1-a9d1c7c9c951&gt; in &lt;module&gt;
  ----&gt; 1 import bind_test
  
  ImportError: /home/dyno/Downloads/futek_usb_linux_x86_64/FUTEK_USB-x86_64/bind_test.cpython-310-x86_64-linux-gnu.so: undefined symbol: _ZN14_FUTEK_USB_DLL13FUTEK_USB_DLL21Get_ADC_Sampling_RateB5cxx11EPvh
  
  </code></pre>
  <p>Here is my PyBind11 file im trying to run</p>
  <pre><code>#include &lt;pybind11/pybind11.h&gt;
  #include &lt;iostream&gt;
  #include &quot;FUTEK_USB_DLL.h&quot;
  #include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;ctime&gt;
  #include &lt;ratio&gt;
  #include &lt;chrono&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fstream&gt;
  
  namespace py = pybind11;
  
  using namespace std;
  
  std::string get_torque(){
  
      _FUTEK_USB_DLL::FUTEK_USB_DLL dll;
  
      PVOID deviceHandle ;
      BYTE channelNumber = 0;
  
      string sn = dll.Get_Device_Serial_Number(0);
      char *serialNumber = new char[sn.length() + 1];
      strcpy(serialNumber, sn.c_str());
      dll.Open_Device_Connection(serialNumber);
      deviceHandle = dll.DeviceHandle;
  
      string boardType = dll.Get_Type_of_Board(deviceHandle);
      string firmVersion = dll.Get_Firmware_Version(deviceHandle);
      string samplingRate = dll.Get_ADC_Sampling_Rate(deviceHandle, channelNumber);
  
      string adc = dll.Normal_Data_Request(deviceHandle, channelNumber);
      return adc;
  
  }
  
  PYBIND11_MODULE(bind_test, handle){
      handle.doc()=&quot;TEST&quot;;
      handle.def(&quot;python_name&quot;, &amp;get_torque);
  }
  </code></pre>
  <p>Any help would be greatly appreciated as I am very stuck on this issue. Here is the repo with the full code <a href="https://github.com/RavenLabsNH/FutekTorqueTransducer" rel="nofollow noreferrer">https://github.com/RavenLabsNH/FutekTorqueTransducer</a></p>