Use Windows dll as dependency (on Windows)

Hello,

Background

I am trying to use the Wiiuse library in my Swift project, and I am working on making a bridging header between it and my project. This is an open-source library, you can find it at GitHub - wiiuse/wiiuse: WiiUse "feature complete" cross-platform Wii Remote access library. I have been following Making a C library available in Swift using the Swift Package Manager this blog post to help me try to figure this out. I am using the latest snapshot of Swift 5.4, for Windows 10.
My goal for right now is to call the wiiuse_version() function from a Swift program, the function simply returns the version string.
Since the blog doesn't mention anything about using DLL files (blog written before pkg manager or windows support available), I have had to try a bunch of things. I first did things as the project mentioned, and my wiiuse bridging repo is my first try at getting this to work. The swift package manager was initialized as type library. I then made a second swift package manager project that is an executable: repo of executable that uses wiiuse Swift bindings. This is all by the tutorial. I didn't know where to put the dll files I compiled, so I was expecting an error that told me it couldn't find them. Didn't get that far, sadly.
Instead, I got this (including the encoding error, but that's because x64 Native Tools in Windows Terminal isn't in utf-8 for some reason):

error: the package at 'C:\Users\Sheen\Swift\CwiiuseTesting\Cwiiuse' cannot be accessed (Error Domain=NSCocoaErrorDomain Code=260 "The file doesnΓÇÖt exist.")

Question 1:

After moving Cwiiuse to the folder SPM was looking for it in, and also doing the below things, I was able to get it to work. How can I separate the two projects into their own folders?

How I got it to work, with some hacky stuff

Probably good to read but you could probably get away without reading it

I couldn't figure out what that was about, so I decided to try to move the whole Cwiiuse project to where it was looking for it, as a last ditch attempt before asking for help. This yielded some improvements:

C:\Users\Sheen\Swift\CwiiuseTesting>swift run
[1/3] Compiling CwiiuseTesting main.swift
<module-includes>:1:10: note: in file included from <module-includes>:1:
#include "../../Headers/wiiusebridge.h"
         ^
C:\Users\Sheen\Swift\CwiiuseTesting\Cwiiuse\Sources\Cwiiuse/../../Headers/wiiusebridge.h:1:2: error: #import of type library is an unsupported Microsoft feature
#import <wiiuse.h>
 ^
C:\Users\Sheen\Swift\CwiiuseTesting\Sources\CwiiuseTesting\main.swift:1:8: error: could not build C module 'Cwiiuse'
import Cwiiuse
       ^
error: fatalError

I don't know what to do with this, either, and online research didn't yield anything. Still nothing about dlls. Then I tried to put the entire source code of the project into where the header is. Predictably, no change. However, after updating the modulemap to point to the wiiuse.h header directly (the main file of the library), I got more progress, something I've seen before with Visual Studio and C++ projects:

C:\Users\Sheen\Swift\CwiiuseTesting>swift run
[1/3] Compiling CwiiuseTesting main.swift
[2/4] Merging module CwiiuseTesting
[3/4] Wrapping AST for CwiiuseTesting for debugging
lld-link: error: could not open 'wiiuse.lib': no such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[3/4] Linking C:\Users\Sheen\Swift\CwiiuseTesting\.build\x86_64-unknown-windows-msvc\debug\CwiiuseTesting.exe
error: fatalError

I moved the pre-compiled wiiuse library files (compiled via visual studio as a plain C project) wiiuse.dll, wiiuse.lib, and wiiuse.exp files into the .build\x86_64-unknown-windows-msvc\debug folder, and it worked fine, and I got a version output, like I hoped. Yay!

This is the working project, with build directory included and everything

Question 2:

How can I use just the wiiuse dlls to work with the project rather than having to compile the entire source of a library each time? How would I do this?

The initial error is likely due to Developer Mode not being enabled on your development setup (alternatively, you must have SeCreateSymbolicLinksPrivillege assigned to your user).

The #import error that you see is expected - please do not use #import but rather use the proper C functionality: #include. #import is an Objective-C specific feature, and should be generally avoided. Header guards are portable and well established, and most modern compilers do not incur a penalty for them (being implicit optimized as a #pragma once).

For the wiiuse.lib issue - you must have an import library for any shared library linking. Note that static library linking does not fully work yet on Windows specifically for Swift code. For C code, you may use static linking into a Swift binary.

If you wish to use prebuilt libraries, you will have to handle everything outside of SPM (SPM does not support system libraries nor pre-packaged libraries on non-Apple platforms). You can simply pass -Xcc -I<path to headers> -Xlinker -L<path to import libraries> to swift-build to work with prebuilt binaries. note the lack of space after -I and -L -- if you add a space, make sure that you add in -Xcc and -Xlinker before the second parameter.

Terms of Service

Privacy Policy

Cookie Policy