<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">Il giorno 10 ago 2016, alle ore 19:18, Oliver Charles <<a href="mailto:ollie@ocharles.org.uk" class="">ollie@ocharles.org.uk</a>> ha scritto:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi all,</div></div></blockquote><div><br class=""></div>Hi,</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">I'm trying to interface with a <a href="http://www.baslerweb.com/en/products/" class="">Basler USB3 camera</a> from a Haskell application, but I'm experiencing some difficulty. The camera comes with a C++ library that makes it fairly straight forward. The following code can be used to acquire a camera source:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace" class="">    PylonAutoInitTerm pylon;</font></div><div class=""><font face="monospace" class="">    CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());</font></div><div class=""><font face="monospace" class="">    camera.RegisterConfiguration( (CConfigurationEventHandler*) NULL, RegistrationMode_ReplaceAll, Cleanup_None);</font></div><div class=""><font face="monospace" class="">    cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Using the inline-c and inline-c-cpp libraries, I am trying to perform this same call from a Haskell executable. I have the following:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace" class="">{-# LANGUAGE QuasiQuotes, TemplateHaskell #-}</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">import qualified Language.C.Inline as C</font></div><div class=""><font face="monospace" class="">import qualified Language.C.Inline.Cpp as C</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">C.context C.cppCtx</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">C.include "pylon/PylonIncludes.h"</font></div><div class=""><font face="monospace" class="">C.include "iostream"</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">C.using "namespace Pylon";</font></div><div class=""><font face="monospace" class="">C.using "namespace std";</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">main :: IO ()</font></div><div class=""><font face="monospace" class="">main =</font></div><div class=""><font face="monospace" class="">  [C.block| void {</font></div><div class=""><font face="monospace" class="">    PylonAutoInitTerm pylon;</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">    CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());</font></div><div class=""><font face="monospace" class="">    camera.RegisterConfiguration( (CConfigurationEventHandler*) NULL, RegistrationMode_ReplaceAll, Cleanup_None);</font></div><div class=""><font face="monospace" class="">    cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;</font></div><div class=""><font face="monospace" class="">  }|]</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">However, when the resulting executable is ran, it hangs - failing to print "Using device".</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><font face="monospace" class="">inline-c</font> generates a <font face="monospace" class="">Test.cpp</font> file, which contains</div><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><font face="monospace" class="">#include "pylon/PylonIncludes.h"</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">#include "iostream"</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">using namespace Pylon;</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">using namespace std;</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">extern "C" {</font></div><div class=""><font face="monospace" class="">void inline_c_Main_0_e23f0c6a0bc10367be76252744bf4e6c74493314() {</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">    PylonAutoInitTerm pylon;</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">    CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());</font></div><div class=""><font face="monospace" class="">    camera.RegisterConfiguration( (CConfigurationEventHandler*) NULL, RegistrationMode_ReplaceAll, Cleanup_None);</font></div><div class=""><font face="monospace" class="">    cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;</font></div><div class=""><font face="monospace" class="">  </font></div><div class=""><font face="monospace" class="">}</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">}</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">If I modify this exact file, I can turn it into something that can be run, by simply adding:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace" class="">int main() {</font></div><div class=""><font face="monospace" class="">  inline_c_Main_0_e23f0c6a0bc10367be76252744bf4e6c74493314();</font></div><div class=""><font face="monospace" class="">}</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">At this point, I can now compile that very C++ code with G++ and run it:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">



<div class="">
<span style="font-family:monospace" class=""><span style="font-weight:bold;color:rgb(84,255,84)" class="">[nix-shell:~/work/circuithub/receiving-station]$</span> g++ Test.cpp -I/home/ollie/work/circuithub/receiving-station/pylon5/include -L/home/ollie/work/circuithub/receiving-station/pylon5/lib64 -Wl,-E -lpylonbase -lpylonu<br class="">tility -lGenApi_gcc_v3_0_Basler_pylon_v5_0 -lGCBase_gcc_v3_0_Basler_pylon_v5_0 -Wl,--enable-new-dtags -Wl,-rpath,/home/ollie/work/circuithub/receiving-station/pylon5/lib64
<br class="">
<br class=""><span style="font-weight:bold;color:rgb(84,255,84)" class="">[nix-shell:~/work/circuithub/receiving-station]$</span> ./a.out  <br class="">GetDeviceDiscoveryInfo: bFunctionClass = 14, bFunctionSubClass = 3, bFunctionProtocol = 0. Device is not an U3V device.
<br class="">GetDeviceDiscoveryInfo: bFunctionClass = 14, bFunctionSubClass = 3, bFunctionProtocol = 0. Device is not an U3V device.
<br class="">Using device acA3800-14um<br class="">
<br class=""></span></div></div><div class=""><span style="font-family:monospace" class=""><br class=""></span></div><div class="">So as we can see, the C++ code is not the problem.</div><div class=""><br class=""></div><div class="">Does anyone know why I don't see the same behaviour from my Haskell application? I imagine there might be some thread trickery happening behind the scenes, but I don't know what to even begin looking for.</div><div class=""><br class=""></div><div class="">Thanks, let me know if you need any more information.</div></div></div></blockquote><div><br class=""></div><div><br class=""></div><div>the first step I would suggest you is to separate each single function call to the library </div><div>interlacing them with print statements to see where exactly the hang happens.</div><div><br class=""></div><div>Then, I’ve never used inline-c-cpp before: which kind of FFI call is C.block supposed to generate? </div><div>I mean a ‘safe’ call or an ‘unsafe’ call? </div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">- Ollie</div></div></div></blockquote><br class=""></div><div>Regards,</div><div>Nicola</div></body></html>