# Win32Api Dll Load

**URL:** <https://forums.sketchup.com/t/win32api-dll-load/105970>\
**Category:** Ruby API\
**Created:** [October 11, 2019, 2:34am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970 "2019-10-11T02:34:18Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ljs](https://avatars.discourse-cdn.com/v4/letter/l/49beb7/32.png) [@ljs](https://forums.sketchup.com/u/ljs)\
**Post date:** [October 11, 2019, 2:34am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/1 "2019-10-11T02:34:18Z")

</div>

Hi  
I have now produced a dll file, and that dll file is win32api in ruby.I’m trying to get a function of the dll file. However, when Ruby tries to load that dll file, an error message appears.

C:/Ruby25-x64/lib/ruby/2.5.0/fiddle.rb:in ‘initialize’: Exec format error (LoadError)  
from C:/from Ruby25-x64/lib/ruby/2.5.0/fiddle.rb:47:in ‘new’  
from C:/Ruby25-x64/lib/ruby/2.5.0/fiddle.rb:47:in ‘dlopen’  
from C:/Ruby25-x64/lib/ruby/2.5.0/Win32API.rb:28:in ‘rescue initialize’  
from C:/Ruby25-x64/lib/ruby/2.5.0/Win32API.rb:24:in ‘initialize’

I also tried AppData\Roaming\SketchUp\SketchUp 2019\SketchUp\Plugins\dll.  
I don’t know why such an error comes out. I want you to let me.  
I will attach the ruby code and the dll code below.

ruby code

```ruby
require "Win32API"

dll_path = File.join("C:/Program Files/SketchUp/SketchUp 2019", "bcdf")

aa = Win32API.new(dll_path, 'Message', 'I')

<dll code>

#include "stdio.h"
#include "Header.h"

extern "C"
{
	DLL_TEST_API int Example(int a, int b)
	{
		return a + b;
	}
}

<header>

#pragma once

#ifdef BCDF_EXPORTS
#define DLL_TEST_API __declspec(dllexport)
#else
#define DLL_TEST_API __declspec(dllimport)
#endif
```

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 11, 2019, 5:26am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/2 "2019-10-11T05:26:14Z")

</div>

> [@ljs](#):
>
> ```ruby
> dll_path = File.join("C:/Program Files/SketchUp/SketchUp 2019", "bcdf")
> 
> ```

`1.` Do **not** put your code files in SketchUp’s program path. They do not belong there.  
All user files, plugins and extensions go in the %AppData% path since version 2014.

`2.` Use the `".dll"` extension for the path as `Win32API.rb` will try to add it anyway, and you’ll do better to help it along.

`3.` The `Win32API` class is deprecated (for a long time) and no longer even appears in the current Ruby documentation for the versions used by SketchUp. The old compiled `"Win32API.so"` file was (a long time since) replaced with a `"Win32API.rb"` file that just made converted calls into other libraries. First into **`DL`** which was later removed. It then was rewritten to make converted calls using the **`Fiddle`** library.  
So you might as well learn to use **`Fiddle`** directly.

> **[Module: Fiddle (Ruby 2.5.5)](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle.html)**
>
> Module : Fiddle - Ruby 2.5.5

> **[Module: Fiddle::Importer (Ruby 2.5.5)](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle/Importer.html)**
>
> Module : Fiddle::Importer - Ruby 2.5.5

> [@ljs](#):
>
> I also tried `"AppData\Roaming\SketchUp\SketchUp 2019\SketchUp\Plugins\dll"`

Yes, the proper place for your code is in an **extension specific** subfolder of the `"Plugins"` folder.  
These **extension specific** subfolders are traditionally prefixed with you author or company namespace identifier, followed by an underscore and the name of the extension.

You cannot just use … `"AppData\Roaming\SketchUp\SketchUp 2019\SketchUp\Plugins\dll"`  
In Ruby you’d need to do …

```ruby
plugins = "SketchUp/SketchUp 2019/SketchUp/Plugins"
dll_path = File.join( ENV["APPDATA"], plugins, 'ljs_dll_test', 'bcdf.dll')

```

… OR (_even easier_) …

```ruby
plugins = Sketchup.find_support_file('Plugins')
dll_path = File.join( plugins, 'ljs_dll_test', 'bcdf.dll')

```

Your error indicates that the file was found and an attempt to load it was made but …  
` Exec format error (LoadError)`  
Fiddle could open it or more likely could not find the export function named `"Message"`.  
Ie, …

> [@ljs](#):
>
> ```ruby
> aa = Win32API.new(dll_path, 'Message', 'I')
> 
> ```

I looked at the C part of your code and I do **NOT** see an exported function by the name **`"Message"`**.

I **do** see one by the name **`"Example"`**.

Also when you post code, please post different languages delimited separately so they can be lexed properly. _See_ …

- [[How to] Post correctly formatted and colorized code on the forum?](https://forums.sketchup.com/t/how-to-colourize-code-on-the-forum-wiki/46189)

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 11, 2019, 5:43am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/3 "2019-10-11T05:43:39Z")

</div>

Also … If you will be writing Ruby extension using **compiled** C … then you can just use Ruby’s global [**`require`**](https://ruby-doc.org/core-2.5.5/Kernel.html#method-i-require) method if you properly name the entry point function.

The name of the file **must** be the same as the entry point function without the **`"Init_"`** prefix.  
The file’s extension can be **`.so`** , **`.dll`** , _etc._

_See_ …

> <https://github.com/SketchUp/ruby-c-extension-examples/blob/main/Hello%20World/src/SUEX_HelloWorld.cpp>

_from_ …

> **[GitHub - SketchUp/ruby-c-extension-examples: Ruby C extension examples](https://github.com/SketchUp/ruby-c-extension-examples)**
>
> Ruby C extension examples. Contribute to SketchUp/ruby-c-extension-examples development by creating an account on GitHub.

💡

* * *

Also there is a book specific to writing Ruby extensions in C.

**“ _Extending Ruby 1.9: Writing Extensions in C_ ”**  
by Dave Thomas …

> **[ext\_ruby.pdf](https://media.pragprog.com/titles/ruby3/ext_ruby.pdf)**
>
> 486.54 KB

---

<div class="post-metadata">

**Author:** ![tt\_su](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/tt_su/32/17_2.png) [@tt\_su](https://forums.sketchup.com/u/tt_su)\
**Post date:** [October 11, 2019, 2:57pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/4 "2019-10-11T14:57:05Z")

</div>

> [@ljs](#):
>
> C:/Ruby25-x64/lib/ruby/2.5.0/fiddle.rb:in ‘initialize’: Exec format error (LoadError)

Did you compile the DLL as 64bit?

Are you able to load the DLL into a sample console app?

---

<div class="post-metadata">

**Author:** ![kengey](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/kengey/32/234545_2.png) [@kengey](https://forums.sketchup.com/u/kengey)\
**Post date:** [October 11, 2019, 3:02pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/5 "2019-10-11T15:02:53Z")

</div>

My first guess would be that the compiled dll is compiled for 32 bit, where SketchUp 2019 is 64 bit.

EDIT: as @tt_su already pointed out I see.

---

<div class="post-metadata">

**Author:** ![kengey](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/kengey/32/234545_2.png) [@kengey](https://forums.sketchup.com/u/kengey)\
**Post date:** [October 11, 2019, 3:07pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/6 "2019-10-11T15:07:21Z")

</div>

Also,

I would not use WIN32API for this, since that is Windows only. I would suggest using ruby Fiddle to wrap your native library: [Module: Fiddle (Ruby 2.5.0)](https://ruby-doc.org/stdlib-2.5.0/libdoc/fiddle/rdoc/Fiddle.html)  
this would give you the opportunity to compile and use your native code on OSX as well.

OR, make a Ruby C++ extension.

---

<div class="post-metadata">

**Author:** ![tt\_su](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/tt_su/32/17_2.png) [@tt\_su](https://forums.sketchup.com/u/tt_su)\
**Post date:** [October 11, 2019, 3:28pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/7 "2019-10-11T15:28:48Z")

</div>

> [@kengey](#):
>
> I would not use WIN32API for this, since that is Windows only. I would suggest using ruby Fiddle to wrap your native library: [Module: Fiddle (Ruby 2.5.0)](https://ruby-doc.org/stdlib-2.5.0/libdoc/fiddle/rdoc/Fiddle.html)  
> this would give you the opportunity to compile and use your native code on OSX as well.

Very good point. Fiddle is the way to interact with libraries from Ruby.

> [@kengey](#):
>
> OR, make a Ruby C++ extension.

The drawback with Ruby C Extensions are that you need to compile a version for each Ruby version it needs to run on (excluding patch versions). So if you don’t need to invoke Ruby, but maybe just do some algorithms etc then a generic dynamic library saves you from the need to recompile per Ruby versions.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 12, 2019, 4:53am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/8 "2019-10-12T04:53:57Z")

</div>

Hmmm… there’s a double echo in here… in Here … in here. 😉

---

<div class="post-metadata">

**Author:** ![kengey](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/kengey/32/234545_2.png) [@kengey](https://forums.sketchup.com/u/kengey)\
**Post date:** [October 12, 2019, 6:38am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/9 "2019-10-12T06:38:10Z")

</div>

Lol, I see. It seems you already had it al pointed out. You should include a TLDR in your long posts 😅

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 12, 2019, 6:52am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/10 "2019-10-12T06:52:19Z")

</div>

> [@kengey](#):
>
> You should include a TLDR in _your_ long posts

Me? I thought that acronym was used by those that actually **didn’t read** because they felt the content was **too long**? (ie, a disclaimer of sorts in case what they post doesn’t fit the conversation as it has developed.)

* * *

> [@ljs](#):
>
> ```c
> #pragma once
> 
> #ifdef BCDF_EXPORTS
> #define DLL_TEST_API __declspec(dllexport)
> #else
> #define DLL_TEST_API __declspec(dllimport)
> #endif
> 
> ```

ThomThom, the above is for **implicit linking** at load time.

I believe FIddle uses **explicit linking**. Ie, it’s [`Fiddle::dlopen()`](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle.html#method-c-dlopen) and [`Fiddle::Importer.dlload()`](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle/Importer.html#method-i-dlload) methods uses **`LoadLibrary`** and **`GetProcAddress`** to access foreign functions through the FFI.

[Microsoft Docs : Link an executable to a DLL : Determine which linking method to use](https://docs.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=vs-2019#determine-which-linking-method-to-use),  
_says in section “[How to link explicitly to a DLL](https://docs.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=vs-2019#how-to-link-explicitly-to-a-dll)”:_

> Because applications call the DLL functions through a pointer, the compiler doesn’t generate external references, so there’s no need to link with an import library. However, you must have a `typedef` or `using` statement that defines the call signature of the exported functions that you call.

I think Fiddle takes care of calling the low level FFI interface calls so all the hard part is done by Fiddle.

* * *

**So is it even needed to export functions** if your DLL will only be explicitly linked (ie, such as using [`Fiddle`](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle.html) or [Ruby-FFI](https://rubygems.org/gems/ffi) etc.,) **?**

---

<div class="post-metadata">

**Author:** ![kengey](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/kengey/32/234545_2.png) [@kengey](https://forums.sketchup.com/u/kengey)\
**Post date:** [October 12, 2019, 7:12am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/11 "2019-10-12T07:12:30Z")

</div>

> [@DanRathbun](#):
>
> Me? I thought that acronym was used by those that actually **didn’t read** because they felt the content was **too long**? (ie, a disclaimer of sorts in case what they post doesn’t fit the conversation as it has developed.)

Well, I should’ve noticed you pointed out Fiddle already. Have never used it myself though.

TLDR was a joke. 🙂

---

<div class="post-metadata">

**Author:** ![ljs](https://avatars.discourse-cdn.com/v4/letter/l/49beb7/32.png) [@ljs](https://forums.sketchup.com/u/ljs)\
**Post date:** [October 14, 2019, 12:31am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/12 "2019-10-14T00:31:06Z")

</div>

It is 64 bits, so it works normally.  
Thank you.

---

<div class="post-metadata">

**Author:** ![tt\_su](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/tt_su/32/17_2.png) [@tt\_su](https://forums.sketchup.com/u/tt_su)\
**Post date:** [October 25, 2019, 10:09am UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/13 "2019-10-25T10:09:43Z")

</div>

> [@DanRathbun](#):
>
> **So is it even needed to export functions** if your DLL will only be explicitly linked (ie, such as using [`Fiddle`](https://ruby-doc.org/stdlib-2.5.5/libdoc/fiddle/rdoc/Fiddle.html) or [Ruby-FFI](https://rubygems.org/gems/ffi) etc.,) **?**

Yes. You need to export functions you want to use externally.

> **[GetProcAddress](https://learn.microsoft.com/en-us/cpp/build/getprocaddress?view=msvc-170&viewFallbackFrom=vs-2019)**
>
> Learn more about: GetProcAddress

> Processes explicitly linking to a DLL call [GetProcAddress](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress) to obtain the address of an **exported** function in the DLL.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 25, 2019, 9:22pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/14 "2019-10-25T21:22:20Z")

</div>

EDIT: So an EXPORTS section of a `.def` file is [needed](https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files?view=vs-2019) …

> _A module-definition or DEF file (\*.def) is a text file containing one or more module statements that describe various attributes of a DLL_. _If you are not using the **\_\_declspec(dllexport)** keyword to export the DLL’s functions, the DLL requires a DEF file._

I’d imagine that the module `.def` is [more portable](https://docs.microsoft.com/en-us/cpp/build/determining-which-exporting-method-to-use?view=vs-2019#pros-and-cons-of-using-def-files) ?

---

<div class="post-metadata">

**Author:** ![tt\_su](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/tt_su/32/17_2.png) [@tt\_su](https://forums.sketchup.com/u/tt_su)\
**Post date:** [October 28, 2019, 2:20pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/15 "2019-10-28T14:20:50Z")

</div>

Depends what you mean by portable. Def files are not cross platform.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [October 28, 2019, 2:55pm UTC](https://forums.sketchup.com/t/win32api-dll-load/105970/16 "2019-10-28T14:55:43Z")

</div>

Yes I **was** thinking “cross platform” as the docs stated that _**\_\_declspec(dllexport)** keyword_ was a Microsoft invention.
