ruby query interface not working? - ruby

I'm having problems with the WIN32OLE#ole_query_interface function.
I use the same source code, as mentioned in the doc of the function:
ie = WIN32OLE.new('InternetExplorer.Application')
ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}')
puts "ie_web_app: = #{ie_web_app.ole_type}"
and the output is:
# => ie_web_app: = IWebBrowser2
but I'd expect the output to be IWebBrowserApp. What am I missing?
BTW: I'm working on a 64bit Win7 and I have now used 2 interpreters to test:
ruby 2.0.0 p353 (2013-11-22) [x64-mingw32]
ruby 1.9.3 p484 (2013-11-22) [i386-mingw32]
here's the coclass from the tlb for reference:
uuid(0002DF01-0000-0000-C000-000000000046), helpstring("Internet Explorer Application.") ] coclass InternetExplorer {
[default] interface IWebBrowser2;
interface IWebBrowserApp;
[default, source] dispinterface DWebBrowserEvents2;
[source] dispinterface DWebBrowserEvents; };
and the relevant part of IWebBrowserApp:
[
uuid(0002DF05-0000-0000-C000-000000000046),
helpstring("Web Browser Application Interface."),
hidden,
dual
]
dispinterface IWebBrowserApp {

The coclass says it implements IWebBrowser2 as its default interface. I suspect that ruby's .ole_type method is using that to generate a printable name. Can you call IWebBrowserApp methods on the resultant interface? If so, it's an IWebBrowserApp, regardless of what gets printed.

Related

SuperCollider * marking the constructor method is not expected

I tried to create a Class and the constructor always gave me a Syntax Error about the *new method then I just copied the Example from the documentation:
MyClass {
// this is a normal constructor method
*new { | arga, argb, argc |
^super.new.init(arga, argb, argc)
}
init { | arga, argb, argc |
// do initiation here
}
}
and still got this:
ERROR: syntax error, unexpected '*', expecting '}'
in interpreted text
line 6 char 5:
*new { | arga, argb, argc |
^
^super.new.init(arga, argb, argc)
-----------------------------------
ERROR: Command line parse failed
-> nil
From my own class i get the same error concerning the constructor. Where am I wrong?
If you check out the Writing Classes helpfile, there's a bit at the top that's easy to miss about where to save your classes.
https://depts.washington.edu/dxscdoc/Help/Guides/WritingClasses.html
NOTE: Class definitions are statically compiled when you launch
SuperCollider or "recompile the library." This means that class
definitions must be saved into a file with the extension .sc, in a
disk location where SuperCollider looks for classes. Saving into the
main class library (SCClassLibrary) is generally not recommended. It's
preferable to use either the user or system extension directories.
Platform.userExtensionDir; // Extensions available only to your user account
Platform.systemExtensionDir; // Extensions available to all users on the machine
It is not possible to enter a class definition into an interpreter
window and execute it.
The the Save As Extension option under the file menu. Then recompile the interpretter and try using your class.

What object does ENV return in Ruby?

There's an ENV variable we all know. It returns an Object. But the return value of ENV is visually similar to a Hash. But it's really not.
For example:
> ENV
=> {"SHELL"=>"/bin/bash", "SESSION_MANAGER"=>"local/archlinux:#/tmp/.ICE-unix/613,unix/archlinux:/tmp/.ICE-unix/613", "COLORTERM"=>"truecolor", "XDG_CONFIG_DIRS"=>"/etc/xdg", "XDG_MENU_PREFIX"=>"xfce-", "SSH_AUTH_SOCK"=>"/tmp/ssh-Al0pdO1R5970/agent.622", "DESKTOP_SESSION"=>"Xfce Session", "SSH_AGENT_PID"=>"623", "GTK_MODULES"=>"canberra-gtk-module:canberra-gtk-module", "XDG_SEAT"=>"seat0", "PWD"=>"/home/sourav", "LOGNAME"=>"sourav", "XDG_SESSION_TYPE"=>"x11", "XAUTHORITY"=>"/home/sourav/.Xauthority", "HOME"=>"/home/sourav", "LANG"=>"en_GB.UTF-8", "XDG_CURRENT_DESKTOP"=>"XFCE", "VTE_VERSION"=>"5603", "INVOCATION_ID"=>"6d4dc7a91cc141e691436cb850e18f8d", "GLADE_CATALOG_PATH"=>":", "XDG_SESSION_CLASS"=>"user", "TERM"=>"xterm-256color", "USER"=>"sourav", "DISPLAY"=>":0.0", "SHLVL"=>"2", "XDG_VTNR"=>"1", "XDG_SESSION_ID"=>"1", "TILIX_ID"=>"f2480263-263e-408f-be36-8105e71256a6", "MOZ_PLUGIN_PATH"=>"/usr/lib/mozilla/plugins", "GLADE_MODULE_PATH"=>":", "XDG_RUNTIME_DIR"=>"/run/user/1000", "GLADE_PIXMAP_PATH"=>":", "JOURNAL_STREAM"=>"9:25041", "XDG_DATA_DIRS"=>"/usr/local/share:/usr/share", "PATH"=>"/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/sourav/.rvm/bin:/home/sourav/.rvm/bin:/home/sourav/.gem/ruby/2.6.0/bin", "DBUS_SESSION_BUS_ADDRESS"=>"unix:path=/run/user/1000/bus", "MAIL"=>"/var/spool/mail/sourav", "_"=>"/home/sourav/.irb", "LINES"=>"24", "COLUMNS"=>"80"}
Which looks similar to:
> ENV.to_h
=> {"SHELL"=>"/bin/bash", "SESSION_MANAGER"=>"local/archlinux:#/tmp/.ICE-unix/613,unix/archlinux:/tmp/.ICE-unix/613", "COLORTERM"=>"truecolor", "XDG_CONFIG_DIRS"=>"/etc/xdg", "XDG_MENU_PREFIX"=>"xfce-", "SSH_AUTH_SOCK"=>"/tmp/ssh-Al0pdO1R5970/agent.622", "DESKTOP_SESSION"=>"Xfce Session", "SSH_AGENT_PID"=>"623", "GTK_MODULES"=>"canberra-gtk-module:canberra-gtk-module", "XDG_SEAT"=>"seat0", "PWD"=>"/home/sourav", "LOGNAME"=>"sourav", "XDG_SESSION_TYPE"=>"x11", "XAUTHORITY"=>"/home/sourav/.Xauthority", "HOME"=>"/home/sourav", "LANG"=>"en_GB.UTF-8", "XDG_CURRENT_DESKTOP"=>"XFCE", "VTE_VERSION"=>"5603", "INVOCATION_ID"=>"6d4dc7a91cc141e691436cb850e18f8d", "GLADE_CATALOG_PATH"=>":", "XDG_SESSION_CLASS"=>"user", "TERM"=>"xterm-256color", "USER"=>"sourav", "DISPLAY"=>":0.0", "SHLVL"=>"2", "XDG_VTNR"=>"1", "XDG_SESSION_ID"=>"1", "TILIX_ID"=>"f2480263-263e-408f-be36-8105e71256a6", "MOZ_PLUGIN_PATH"=>"/usr/lib/mozilla/plugins", "GLADE_MODULE_PATH"=>":", "XDG_RUNTIME_DIR"=>"/run/user/1000", "GLADE_PIXMAP_PATH"=>":", "JOURNAL_STREAM"=>"9:25041", "XDG_DATA_DIRS"=>"/usr/local/share:/usr/share", "PATH"=>"/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/sourav/.rvm/bin:/home/sourav/.rvm/bin:/home/sourav/.gem/ruby/2.6.0/bin", "DBUS_SESSION_BUS_ADDRESS"=>"unix:path=/run/user/1000/bus", "MAIL"=>"/var/spool/mail/sourav", "_"=>"/home/sourav/.irb", "LINES"=>"24", "COLUMNS"=>"80"}
But:
> ENV.to_h.eql?(ENV)
=> false
So what kind of object does ENV return?
It's a custom Object with Hash-like functionality mostly implemented in C.
https://github.com/ruby/ruby/blob/trunk/hash.c#L4944
There is nothing in the Ruby Language Specification that requires ENV to be implemented in any particular way. As long as it responds to the right messages in the right way, it can be anything it wants.
For example, in Rubinius, ENV is implemented in a class called Rubinius::EnvironmentVariables that implements part of the Hash protocol and also mixes in Enumerable: https://github.com/rubinius/rubinius/blob/master/core/env.rb .

Unable to see the plugin compiled in the custom wireshark run?

I am following the foo example given in the wireshark documentation.
I am able to build the foo code plugin. I am using wireshark 3.0.1 version. In the workroot folder, I have updated the target - PLUGIN_SRC_DIRS - plugins/epan/foo just before gryphon.
I can see that my code builds because I got some compilation error which I was able to fix it.
My foo code lives inside the plugins/epan folder.
I am running custom wireshark - sudo ./run/wireshark
There is a surprise here that I can't see even gryphon protocol field in the running wireshark. So in order to test this, I am typing foo or gryphon in that display filter and it turns red and it say foo is neither a protocol nor a protocol field. I am using Ubuntu 16.04 LTS to build it. The build goes fine.
Here is packet-foo.c
#include "config.h"
#include <epan/packet.h>
#include "packet-foo.h"
static int proto_foo = -1;
static int dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_);
void
proto_register_foo(void)
{
proto_foo = proto_register_protocol (
"FOO Protocol", /* name */
"FOO", /* short name */
"foo" /* abbrev */
);
}
void
proto_reg_handoff_foo(void)
{
static dissector_handle_t foo_handle;
foo_handle = create_dissector_handle(dissect_foo, proto_foo);
dissector_add_uint("udp.port", FOO_PORT, foo_handle);
}
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_)
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
return tvb_captured_length(tvb);
}
Here is the packet-foo.h
#define FOO_PORT 1234
The CMakeLists.txt is here, this is actually a copy of gryphon.
So, I am wondering if gryphon wasn't recognised that means foo won't be recognised too. So, this file might be a source of problem.
include(WiresharkPlugin)
# Plugin name and version info (major minor micro extra)
set_module_info(foo 0 0 4 0)
set(DISSECTOR_SRC
packet-foo.c
)
set(PLUGIN_FILES
plugin.c
${DISSECTOR_SRC}
)
set_source_files_properties(
${PLUGIN_FILES}
PROPERTIES
COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
register_plugin_files(plugin.c
plugin
${DISSECTOR_SRC}
)
add_plugin_library(foo epan)
target_link_libraries(foo epan)
install_plugin(foo epan)
file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
CHECKAPI(
NAME
foo
SWITCHES
-g abort -g termoutput -build
SOURCES
${DISSECTOR_SRC}
${DISSECTOR_HEADERS}
)
Merely changing the plugin isn't sufficient.
You need to modify the top make file so that foo is actually installed.
vim CMakeListsCustom.txt.example
Firstly, uncomment - line number 16
plugins/epan/foo
Since your foo lives inside plugins/epan/foo
Now, rename this example to
mv CMakeListsCustom.txt.example CMakeListsCustom.txt
vim CMakeLists.txt
Insert a line number around 1408-
plugins/epan/foo
After that, do make
and then sudo make install
Here is the working copy -
https://github.com/joshis1/WiresharkDissectorFoo

Elixir NIF- Hello World example on x64 Mac OSX

Hi I'm trying to get the Hello World example for Erlang NIF (Native Implemented Function) shown here
http://www.erlang.org/doc/man/erl_nif.html
to work from Elixir on OSX 64bit.
First I create the C-code:
/* niftest.c */
#include "erl_nif.h"
static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1);
}
static ErlNifFunc nif_funcs[] =
{
{"hello", 0, hello}
};
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)
Then I successfully compile it using gcc for 64 bit architecture as suggested here
Erlang NIF Test -- OS X Lion
gcc -undefined dynamic_lookup -dynamiclib niftest.c -o niftest.so -I /usr/local/Cellar/erlang/R14B02/lib/erlang/usr/include
which produces the necessary file niftest.so that I should be able to interface-into from Erlang/Elixir. My Elixir (niftest.ex) looks like this (inspired by a more complex example reported here):
defmodule Niftest do
#onload :init
def init() do
:erlang.load_nif("./niftest", 0)
:ok
end
def hello() do
"NIF library not loaded"
end
end
Now with niftest.so and niftest.ex in the same directory I fire up elixir using iex and type in Niftest.hello and all I get back is: "NIF library not loaded"
Am I missing a vital step? - please help!
The load of the library is failing silently. You can assert that it succeeds using:
:ok = :erlang.load_nif("./niftest", 0)
This results in an error:
** (MatchError) no match of right hand side value:
{:error, {:bad_lib, 'Library module name \'niftest\' does not match calling module \'\'Elixir.Niftest\'\''}}
niftest.ex:4: Niftest.init/0
That happens because a NIF lib can only be called from its "owning" module. The name of that module is the first argument to the ERL_NIF_INIT macro, so you can fix this by changing that call and recompiling:
ERL_NIF_INIT(Elixir.Niftest,nif_funcs,NULL,NULL,NULL,NULL)
There is also a typo in the load hook. It should be:
#on_load :init

How to interface more complex shared library?

I'm trying to dynamically call functions of external library on Linux/Unix system.
I have some success with dl library but only when primitive C types are used and arguments are passed by value:
require 'dl/import'
module LibM
extend DL::Importer
dlload 'libm.so'
extern 'double sin(double)'
end
puts LibM.sin(3.14159265358979323846 / 2) # 1.0
However how can be interfaced functions using more complex types like C structs or if arguments are pointers where results of the call are stored ?
module LibX11
extend DL::Importer
dlload 'libX11.so.6'
extern 'Display *XkbOpenDisplay (char *display_name, int *event_rtrn, int *error_rtrn, int *major_in_out, int *minor_in_out, int *reason_rtrn)'
end
Display is a big struct, at event_rtrn is stored some result etc.
I've taken a look at DL::CStructBuilder and it looks can do the job, but as the documentation is very brief and no working examples found I'm lost here how it has to be properly used.
I have to add standard Ruby 1.9 modules have to be used (if possible) as installation of additional gems on the target machine is prohibited.
I am facing with interfacing with C libraries in this period (I am writing a wrapper for libgtop), and I choosed to use ffi, which is quite well documented (although the documentation sometimes is a bit outdated) and above all its mailing list is full of people who give you an helping hand when you are in trouble.
So I propose you a solution which uses ffi:
require 'ffi'
module LibX11
extend FFI::Library
ffi_lib 'libX11.so.6'
# Display *XkbOpenDisplay (char *display_name, int *event_rtrn, int *error_rtrn, int *major_in_out, int *minor_in_out, int *reason_rtrn)
attach_function :XkbOpenDisplay, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :pointer
end
Then you have to describe the Display struct layout, like written here:
class Display < FFI::Struct
layout :value, :double,
:other_value, :char,
...
end
And then you do something like this:
p1 = FFI::MemoryPointer.new(:char)
p2 = FFI::MemoryPointer.new(:int)
p3 = FFI::MemoryPointer.new(:int)
p4 = FFI::MemoryPointer.new(:int)
p5 = FFI::MemoryPointer.new(:int)
p6 = FFI::MemoryPointer.new(:int)
# write to pointer if needed, otherwise it is a null pointer
# p1.write_char('a')
# p2.write_int(1)
# ...
struct_pointer = LibX11.XkbOpenDisplay(p1, p2, p3, p4, p5, p6)
# read the struct
struct = Display.new(display_struct_pointer)
p Hash[ s.members.map { |m| [ m, s[m] ] } ]
I didn't tested the code, but it should be roughly correct. Let me now if it isn't.
After some research about DL on ruby 2.0 I found that it is deprecated and replaced with fiddle, you would consider to use it rather than DL if you can't use FFI. Fiddle seems to be available for ruby 1.9.3 and 1.9.2 too

Resources