.dll accessing - how to?
-
I've found myself needing to access a dll file. It is compiled by others, but neither of us are particularly sure how to exchange data from SU and the dll.
<EDIT> - reworking code - but I'll still take any tips you've got as to how to access .dll files
-
Generall, first thing to do as you don't have the actual source code for the .dll, is you need to know the exact name of the functions you want to access. For that, you need a program like DLL Export Viewer: http://www.nirsoft.net/utils/dll_export_viewer.html or PE Explorer: http://www.heaventools.com/overview.htm Once you have those function names along with their input and return types, you'll need to write code to access them and pass the necessary data to, and from the .dll ...
If you're using a scripting language like Javascript, you may have to code up an intermediate .dll to translate javascript data to a form the target .dll can use. Normally, unless the target .dll has a scripting language interface coded into it, ie; it's been linked to a javascript library so those functions are part of the .dll or can be called by it, the data are passed using standard C/C++ calling conventions.
In a nutshell, it's generally a PITA if you don't have the source code ...
Cheers.
-
Thanks Jeff, I'll look into those links. I should clarify a bit though. I do have access to the source code. I'm working with the people who wrote and compiled the .dll file.
Is there anything they need to do to their .dll to make it so that ruby can access it easier? Is there some compiler switch they can use? Its all very foreign to me.
-
Hi Chris ...
Ah, the source code is available, great! My explanation is a bit of programmer-speak, but I think you'll get it ...The standard way to have Ruby access C/C++ functions is to have Ruby-callable modules and function names. That is, the .dll C/C++ code needs to be able to export module(s) with callable Ruby function(s) in them. Here is a very simple example of what I mean: http://www.flipcode.com/archives/Calling_C_Functions_From_Ruby.shtml
/* Copyright? We don't need no stinkin copyright! */ #if defined (WIN32) # include "windows.h" #define EXPORT_FUNC _declspec (dllexport) #endif #include "ruby.h" #ifdef _NO_NUM2DBL_ extern double num2double(val) VALUE val; { struct RFloat* flt; if (NIL_P(val)) return 0; flt = RFLOAT(f_float(0, val)); return flt-value; } #endif static VALUE Sum(obj,arg1,arg2) VALUE obj,arg1; { double val1 = NUM2DBL(arg1); double val2 = NUM2DBL(arg2); return rb_float_new(val1+val2); } static VALUE mRUBBER; void InitializeRubber() { mRUBBER = rb_define_module("Rubber"); rb_define_module_function(mRUBBER, "Sum", Sum, 2); rb_define_const(mRUBBER, "TestConst", INT2NUM(38)); } EXPORT_FUNC void Init_rubber() { InitializeRubber(); }
A few things to notice: They've included the windows.h and ruby.h header files. These files contain the C "templates" for accessing necessary Windows and Ruby functions. You must also have linkable windows and ruby libraries in the compiler path as well.
Then they defined a couple of internal native C functions, num2double and Sum. A module to be called by Ruby, "Rubber" is contained in the InitializeRubber function. num2double and Sum will be called internally by InitializeRubber to do it's calculations for "Rubber".
The EXPORT_FUNC directive makes sure the "Rubber" module is exported externally so Ruby can "require" it.
#Simple ruby script to test ruby-C binding require "rubber" print "Testing\n" print "---------------------------------------------------\n" print "C Constant test ; "+Rubber;;TestConst.to_s()+"\n" print "C Function test ; "+Rubber.Sum(100.75,50).to_s()+"\n"
Here, Ruby has required the "rubber" module in an .rb script and passed some input parameters to Rubber.Sum. Rubber.Sum will then call the internal num2double and Sum functions in the .dll and return the correct answer for further formatting using the .to_s Ruby built-in ...
In a nutshell, you'll need to change the source code so that the functions you want to access have Ruby-callable names and you'll know what kind of variable types need to be passed to the function, and what will be returned. I think if you point your coder people to the link I provided, they should get the gist of it ...
Hope this is helpful. Cheers
-
And.. the DLL entry point.. "
Init_rubber()
" means that the compiled filename must be case-SAME as the suffix after "Init_
", otherwise Ruby'srequire()
method will puke up an "Entry point not found" error.It's a nice feature actually.. means 'theives' cannot just rename someone else's DLL, and distro it as their own.
-
Hi, we've been working on this for the last few days with no luck yet.
Just the line
require 'test4dll.dll'
bugsplats SketchUp on loading. So I'm not even getting ruby to let me load the dll. Does that mean the .dll is compiled incorrectly?I do have the source code for this test dll I could PM if someone has the ability to look it over and see what it needs to make it more ruby friendly.
-
@chris fullmer said:
Does that mean the .dll is compiled incorrectly?
Hard to tell unless you describe the steps in compilation.
Be sure all methods callable from Ruby return a VALUE, even if it's just Qnil.
-
PM sent Chris.
-
@chris fullmer said:
require 'test4dll.dll'
bugsplats SketchUp on loading. So I'm not even getting ruby to let me load the dll. Does that mean the .dll is compiled incorrectly?Anye. God the same problem. I followed the C Extension tutorial for Ruby, but that didn't play well with SU Ruby. TBD's CExt sample project got me set up. (No idea what magic he's done to it though. I also needed help from him and AdamB to get ti working under OSX as well...)
-
@chris fullmer said:
Hi, we've been working on this for the last few days with no luck yet.
Just the line
require 'test4dll.dll'
bugsplats SketchUp on loading. So I'm not even getting ruby to let me load the dll. Does that mean the .dll is compiled incorrectly?I do have the source code for this test dll I could PM if someone has the ability to look it over and see what it needs to make it more ruby friendly.
Chris,
If you've compiled this DLL, why not launch Sketchup from VisualC and look where it crashes?
And what flags are you using to compile this DLL?Adam
-
I want to access the functions of the Skp2AcadHlr.dll, because i want to export a hiddenlineremovel from within a ruby script. Can somebody help me?
-
Guy,
Generally, you're not going to be able to do anything useful with the entrypoints its exposes. Particularly not from Ruby.
Not sure if it helps but here's a quick tutorial on output very high resolution hidden line images using LightUp..
http://www.light-up.co.uk/index.php?t=story&p=101
Adam
Advertisement