# Ruby/DL problem

**URL:** <https://www.ruby-forum.com/t/ruby-dl-problem/191015>\
**Category:** Ruby\
**Created:** [July 2, 2010, 5:37pm UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015 "2010-07-02T17:37:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 2, 2010, 5:37pm UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/1 "2010-07-02T17:37:21Z")

</div>

Hello,

I have very little experience with dl. But I want to use it to  
call SetEnvironmentVariable() from Win32. I could use FFI but cannot,  
since this  
script will be supplied to a customer where it is difficult to install.

SetEnvironmentVariable on  
MSDN [SetEnvironmentVariableA function (processenv.h) - Win32 apps | Microsoft Learn](http://msdn.microsoft.com/en-us/library/ms686206(v=VS.85).aspx)

reading sparse, old, and cryptic documentation I came up with this  
snippet,  
which of course does not work

require ‘dl/import’

module Win32  
extend DL::Importer  
extern “int SetEnvironmentVariableA( char\* lpName, char\* lpValue)”  
extern “int GetEnvironmentVariableA( char\* lpName, char\* lpValue, int  
size)”  
end

buff = Array.new( 256, 0).pack(“c\*”)  
Win32.GetEnvironmentVariableA( “ENV\_VAR”, buff, 255)  
puts buff.unpack(“a\*”)

this is the error i get  
D:/ruby/usr/lib/ruby/1.9.1/dl/import.rb:194:in `import_function': undefined method `sym’ for nil:NilClass (NoMethodError)  
from D:/ruby/usr/lib/ruby/1.9.1/dl/import.rb:118:in `extern' from test.rb:5:in `module:Win32’  
from test.rb:3:in `’

machine is WinXP  
ruby 1.9.1 (2008-10-28 revision 19983) [i386-mswin32\_80]

can anybody suggest a better signature ?

Aston

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 2, 2010, 7:16pm UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/2 "2010-07-02T19:16:22Z")

</div>

On Fri, Jul 2, 2010 at 10:37 AM, Aston [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> which of course does not work  
> Win32.GetEnvironmentVariableA( “ENV\_VAR”, buff, 255)  
> ruby 1.9.1 (2008-10-28 revision 19983) [i386-mswin32\_80]
> 
> can anybody suggest a better signature ?
> 
> Aston

I can’t help you with your issue, but I’m curious why it’s necessary.  
The MSDN page you link to says SetEnvironmentVariable is only for the  
current process. Doesn’t ENV do what you need?

irb(main):001:0\> ENV[‘FOO’]=‘bar’  
=\> “bar”  
irb(main):002:0\> `echo %FOO%`  
=\> “bar\n”  
irb(main):003:0\>

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 3, 2010, 5:22pm UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/3 "2010-07-03T17:22:07Z")

</div>

----- Original Message ----

> module Win32  
> D:/ruby/usr/lib/ruby/1.9.1/dl/import.rb:194:in `import\_function’: undefined  
> Aston

hmm, nobody here using Ruby.DL ?

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 3, 2010, 5:50pm UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/4 "2010-07-03T17:50:48Z")

</div>

On Jul 3, 12:20 pm, Aston [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > this
> 
> > this is the error i get
> 
> > Aston
> 
> hmm, nobody here using Ruby.DL ?

Is not DL the problem, but the version you’re using. revision 19983 is  
_way_ older than latest released one:

Pathlevel 378 was revision 26273

Lurking in the NEWS and ChangeLog pointed several changes in DL.

Trying your example with latest RubyInstaller 1.9.1 release:

C:\Users\Luis\Desktop\>ruby -v t.rb  
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-mingw32]  
C:/Users/Luis/Tools/Ruby/ruby-1.9.1-p378-i386-mingw32/lib/ruby/1.9.1/  
dl/import.rb:116: warning: instance variable @type\_alias not  
initialized  
C:/Users/Luis/Tools/Ruby/ruby-1.9.1-p378-i386-mingw32/lib/ruby/1.9.1/  
dl/import.rb:194: warning: instance variable @handler not initialized  
C:/Users/Luis/Tools/Ruby/ruby-1.9.1-p378-i386-mingw32/lib/ruby/1.9.1/  
dl/import.rb:194:in `import_function': undefined method `sym’ for  
nil:NilClass (NoMethodError)  
from C:/Users/Luis/Tools/Ruby/ruby-1.9.1-p378-i386-mingw32/lib/  
ruby/1.9.1/dl/import.rb:118:in `extern' from t.rb:5:in `module:Win32’  
from t.rb:3:in `’

Which brings the question, why bother on doing this way when Ruby does  
it out of the box?

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 4, 2010, 3:03am UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/5 "2010-07-04T03:03:16Z")

</div>

Hi,

At Sat, 3 Jul 2010 00:37:00 +0900,  
Aston wrote in [ruby-core:30996]:

> module Win32  
> extend DL::Importer  
> dlload “kernel32” # is this correct DLL?  
> extern “int SetEnvironmentVariableA( char\* lpName, char\* lpValue)”  
> extern “int GetEnvironmentVariableA( char\* lpName, char\* lpValue, int size)”  
> end

The following patch refines the error messages.

diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb  
index fd23bc9…f9e8faf 100644  
— a/ext/dl/lib/dl/import.rb  
+++ b/ext/dl/lib/dl/import.rb  
@@ -194,8 +194,12 @@ module DL  
return ptr  
end

- def handler
- 

```
 @handler or raise "call dlload before importing symbols and 

```

functions"

- end
- def import\_symbol(name)

- 

```
 addr = @handler.sym(name)

```

- 

```
 addr = handler.sym(name)
 if( !addr )
   raise(DLError, "cannot find the symbol: #{name}")
 end

```

@@ -203,7 +207,7 @@ module DL  
end

```
 def import_function(name, ctype, argtype, call_type = nil)

```

- 

```
 addr = @handler.sym(name)

```

- 

```
 addr = handler.sym(name)
 if( !addr )
   raise(DLError, "cannot find the function: #{name}()")
 end
```

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [July 6, 2010, 1:38am UTC](https://www.ruby-forum.com/t/ruby-dl-problem/191015/6 "2010-07-06T01:38:15Z")

</div>

On Sun, Jul 04, 2010 at 10:02:28AM +0900, Nobuyoshi N. wrote:

> The following patch refines the error messages.

I like this, so I’ve added it. Thanks Nobu!
