I'd like to bump this and see if anyone has any ideas. I do not see what 
could change. 

To provide some background, if it would help, 

The code referenced by Eric runs at load time, to generate a set of methods 
(called _jcall) for different types of inputs. For each such input type, a 
method definition is created within a quote block, and then that quote 
block is eval-ed to actually define the method. 

The reason separate functions are defined, rather than doing this by 
dynamic dispatch, is that a key part of the method is a ccall. The argument 
types to the ccall needs to be determined at compile time, and hence in 
this case we define a separate method for each input type, rather than use 
dynamic dispatch. This code works correctly in 0.4 (and 0.3), but fails 
with an UndefRefError in 0.5. 

Any ideas? 

Thanks!
-
Avik
 

On Friday, 24 June 2016 19:50:01 UTC+1, Eric Davies wrote:
>
> I have an intuition that this should be possible because the ccall depends 
> on the input types, but I can't figure out how to make it work. I've tried 
> a few things and they all seem to result in an UndefVarError or 
> UndefRefError.
>
> I want to turn this:
> for (x, y, z) in [ (:jboolean, :(jnifunc.CallBooleanMethodA), :(jnifunc.
> CallStaticBooleanMethodA)),
>                   (:jchar, :(jnifunc.CallCharMethodA), :(jnifunc.
> CallStaticCharMethodA)),
>                   (:jbyte, :(jnifunc.CallByteMethodA), :(jnifunc.
> CallStaticByteMethodA)),
>                   (:jshort, :(jnifunc.CallShortMethodA), :(jnifunc.
> CallStaticShortMethodA)),
>                   (:jint, :(jnifunc.CallIntMethodA), :(jnifunc.
> CallStaticIntMethodA)),
>                   (:jlong, :(jnifunc.CallLongMethodA), :(jnifunc.
> CallStaticLongMethodA)),
>                   (:jfloat, :(jnifunc.CallFloatMethodA), :(jnifunc.
> CallStaticFloatMethodA)),
>                   (:jdouble, :(jnifunc.CallDoubleMethodA), :(jnifunc.
> CallStaticDoubleMethodA)),
>                   (:Void, :(jnifunc.CallVoidMethodA), :(jnifunc.
> CallStaticVoidMethodA)) ]
>     m = quote
>         function _jcall(obj,  jmethodId::Ptr{Void}, callmethod::Ptr{Void}, 
> rettype::Type{$(x)}, argtypes::Tuple, args... )
>             if callmethod == C_NULL #!
>                 callmethod = ifelse( typeof(obj)<:JavaObject, $y , $z )
>             end
>             @assert callmethod != C_NULL
>             @assert jmethodId != C_NULL
>             if(isnull(obj)); error("Attempt to call method on Java NULL"); 
> end
>             savedArgs, convertedArgs = convert_args(argtypes, args...)
>             result = ccall(callmethod, $x , (Ptr{JNIEnv}, Ptr{Void}, Ptr{
> Void}, Ptr{Void}), penv, obj.ptr, jmethodId, convertedArgs)
>             if result==C_NULL; geterror(); end
>             if result == nothing; return; end
>             return convert_result(rettype, result)
>         end
>     end
>     eval(m)
> end
>
> Into something that works on 0.5. Code located here: 
> https://github.com/invenia/JavaCall.jl/blob/compat-0.5/src/core.jl#L196
>
> I've learned tricks to deal with the 0.4 function eval pattern, but they 
> don't seem to work with ccall, which is a special feature that requires 
> some arguments to be static and known at compile time.
>
> Anyone have any tips?
>
> Thanks,
> Eric
>

Reply via email to