How to export `DLLMain`

Hi!!

I’m relatively new to Odin, and completely new to exporting C ABI.

I would like to export an empty DLLMain DLL, which would look like this in C:

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
    return TRUE;
}

In Odin, I’d do

package main

import "core:sys/windows"

@export
DllMain :: proc(
    instance: windows.HINSTANCE,
    reason: windows.DWORD,
    reserved: rawptr,
) -> windows.BOOL {
    return true;
}

and then attempt to build with odin build . -build-mode:dll -target:windows_amd64 -o:size

This results in the following error:

/home/sylphrena/.local/bin/Odin/base/runtime/entry_windows.odin(10:13) Error: Non unique linking name for procedure 'DllMain'
	other at /mnt/Storage/Documents/Various/Random/test.odin(6:1)
	... Main :: proc "system" (hinstDLL: rawptr, fdwReason: u32, lpRese ...
	            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

Any hints, tips or pointers would be very much appreciated! Thank you! <3

When exporting DLL in Odin you do not write DLLMain yourself. The base:runtime library handles the OS entry points for you. All you need to do is write the main procedure, as always.

package my_lib

import "core:fmt"

main :: proc() {
  fmt.println("My library attached to some process! Oh yes!")
}

If you look in the source code for the DLL entry point, you’ll find that Odin already has defined the DLLMain function for you. This is what the error message you have posted is complaining about – this function is already defined, and you were trying to define it the second time.

You can then build the DLL with:

odin build <dir> -build-mode:dll

In order to export procedures for the C ABI you can use @(export) attribute on the functions. You can also use core:c to import the C types to use in your exported procedures (you can, if you know the ABI to use simple types, e.g. on linux long is the same as Odin’s int, and C’s int is the same as i32 in Odin for all platforms)

package my_lib

import "core:c"

@(export)
sum :: proc(a,b: c.int) -> c.int {
  return a+b
}
1 Like

Thank you very much for the detailed reply! It was very informative and helpful :smiley: