How to build a string for icxx?

cxx

#1

Hi - I’m using the Cxx.jl package to get at data using a C++ library. I have a line that looks like this…

tracks = icxx"return $(he.galleryEvent).getValidHandle<gm2truth::TrackingActionArtRecordCollection>($(trackingActionSpect.artInputTag));"

This all works great, including the interpolation. The problem is that the type in the template can change and I want that to be set by a string. That is I want something like…

s = "gm2truth::SomeOtherType"  # julia string
otherThings = icxx"return $(he.galleryEvent).getValidHandle<$s>($(trackingActionSpect.artInputTag));"

Of course this doesn’t work because $s isn’t a C++ type. It’s a string. But I want it to be the type that the string says.

Is there a way to do this? Thanks!!! – Adam


#2

Ok, this is a tough one.

Try something like:

s = "gm2truth::SomeOtherType"  # julia string
code = "return \$(he.galleryEvent).getValidHandle<$s>(\$(trackingActionSpect.artInputTag));"
otherThings = @eval @icxx_str $code

Notice, in code construction, the \$ before C++ objects and $ before pure code string.


#3

Hi - Thanks very much for the good suggestion. Note that @icxx_std should be @icxx_str. This works in the global REPL but not in a function. …

function getRecord(he::HeistEvent, rs::HeistRecordSpec)

   code = "return \$(he.galleryEvent).getValidHandle<$(rs.productName)>(\$(rs.artInputTag));"
   println(code)
   return @eval @icxx_str $code
end

Then in the REPL.

...
tracks = getRecord(hev, tas)

# The function prints out the code string -- looks good to me
return $(he.galleryEvent).getValidHandle<gm2truth::TrackingActionArtRecordCollection>($(rs.artInputTag));

# But then...
ERROR: LoadError: UndefVarError: he not defined
Stacktrace:
 [1] getRecord(::Heist.HeistEvent, ::Heist.HeistRecordSpec) at /Users/lyon/Development/julia/julia-centos6-prod8/mypkgs/Heist.jl/src/Heist.jl:111
 [2] include_from_node1(::String) at ./loading.jl:576
 [3] include(::String) at ./sysimg.jl:14
 [4] process_options(::Base.JLOptions) at ./client.jl:305
 [5] _start() at ./client.jl:371
while loading /vagrant/heistTest.jl, in expression starting on line 20

It doesn’t seem to understand the function argument.

Indeed this seems to be a tough one!


#4

The text itself needs to be fixed at macro expansion time, though you can use @eval to build the text up dynamically. That said, the best solution to your problem is probably to use the julia-side representation of the C++ type:

s = cxxt"gm2truth::SomeOtherType"
tracks = icxx"return $(he.galleryEvent).getValidHandle<$s>($(trackingActionSpect.artInputTag));"

which should work well, because the text is fixed at macro expansion time (though the s is allowed to vary at runtime).


#5

Thanks!! That’s what I needed to know. Here’s what I ended up with…

function getRecord(he::HeistEvent, rs::HeistRecordSpec)
   s = @eval @cxxt_str $(rs.productName)
   return icxx"return $(he.galleryEvent).getValidHandle<$s>($(rs.artInputTag));"
end

@Keno & @cdsousa - I appreciate your help – Adam