windows dll for rawhid

andersod2

Member
I'm unsure if this has already been done (I didn't find anything when searching the forum) or if anyone cares, but I created a port of the rawhid code+Makefile which will make a windows dll which can be imported into standard msvc programs. I have this working for a basic c++ console app so there's no reason why it should work also for other msvc project types. I've tested this as working on mingw for Ubuntu and natively on mingw and cygwin for windows (notice the CC line is changed to just "gcc" when in the native windows environment, not cross-compiling from ubuntu). My make program has issues in cygwin, so I did not do a full test of the makefile with it, but the raw gcc commands work so the makefile should work as well.

Once the dll is created, you can import it into a c++ project using loadllibrary() or the easier way is to use the lib command, which is explained in the makefile, to create a .lib file.
 

Attachments

  • rawhid_dll.zip
    4.1 KB · Views: 810
Very minimalist and elegant. I think it would be helpful if you could include the compiled dll, as that would help users who do not use the same compiler as you (the nice thing about DLLs is you can link to them from other languages).
 
Thanks crlab -
Here is an updated version that has the included dll, .def, and .a files from the makefile - compiled from mingw for windows. I never actually ended up using rawhid myself, so I'm interested to see if anyone ends up using this.

View attachment rawhid_dll.zip
 
thanks

Thanks. Your dll works very nicely. I wish I had checked the forum earlier as this would have saved me some effort. For anyone who wants to try it, I have included a Windows executable (with Delphi source) and an Arduino sketch that demonstrates sending and receiving data via raw HID. The nice thing about raw HID is typically you do not need to install drivers, in contrast to deploying the virtual serial port. Paul has a nice web page with raw HID examples, but it is somewhat tricky to support in many programming languages. This elegant dll is very useful.
 

Attachments

  • rawhid_dll_w_example.zip
    216.5 KB · Views: 1,208
Nice! I'm glad someone ended up actually making some use of it. When I started this project I thought HID was the only real usb support that existed because the usb_serial library had all the typical uart stuff associated with it. That tricked me into thinking that usb_serial was bound to uart serial communication speeds - little did I know that the uart communication stuff is basically ignored and it's actually full speed usb bulk mode...so I went with that after taking the time to make this HID dll. Ah well, live and learn. My next project might include making native linux usb drivers for the teensy, although the existing drivers are probably good enough.
 
Thank you, andersod2!

This seems like just what I have been looking for.
It's been way too long since I've written (or read) any Pascal, but it looks pretty clear.
You wouldn't have a short C example and associated makefile available, would you?

Dave
 
Hi Dave -
What development environment are you using? I'm confused by you asking for a makefile since if you're using C with makefiles, that implies you are on a linux-based system, or using MinGW or Cygwin, in which case this DLL would probably not be the best choice for you to use. For those environments, it's better to go with the regular rawhid code+test stuff that is provided with the Teensy. I only created the DLL for ease of use with native windows tools (such as MSVC). If you're using MSVC, building a project is as simple as creating the .lib file from the dll (instructions in the Makefile provided), then just adding that .lib file as a dependency in your project. From there everything should work the same as it does in the hid_listen / test_rawhid code with the teensy. (I think my original test was using the rawhid_test.c provided with rawhid). If you need a sample of an MSVC project that uses it, I can provide that, otherwise, I'd need to know more about your setup. Sorry if this doesn't help much!
 
Yes, I have been using MinGW under Win7, but I'm not locked into that.
I do plan on running my application under Windows, as a command line project.

I'm somewhat hampered by working on a Corporate PC at the moment, with no real admin rights.
This limits me as to what I can obtain and install, and what control I have over system settings.
I have requested installation of Visual Studio (2008, v. 9.0), but that will probably take at least a few days into next week...
An example in VC would probably be helpful, thanks!

I did download and try to build rawhid, but was running into errors there.
 
Last edited:
Mingw can use Visual Studio DLLs, as long as they are C and not C++.

There are different Mingw versions with different win32 platform libraries/headers. The one I'm currently using can't compile the raw HID stuff either, even though it ships with the required headers (extremely obscure compile errors).
 
I know this doesn't help much for compiling natively on Windows, but I've always had no problem cross-compiling from Linux.

On Ubuntu, just use "sudo apt-get install mingw32 mingw32-binutils mingw32-runtime" to install the cross compiler. Then edit the Makefile to select Windows, and run "make". That's exactly how I create all the Windows executables PJRC publishes.

If all else fails, you can always just put Ubuntu 12 (long term support version) on a virtual machine....
 
Paul, the cross-platform support with both rawhid and usb_serial is GREAT -- I've compiled this code on windows mingw, cygwin, Ubuntu cross-compiled mingw (from a VM), and raspian linux for the raspberry pi and all with no changes to code or makefiles. The VM option is a great one as well, and is surprisingly easy to set up.

Dave, I will try to create an msvc sample this weekend if I get some time, but I agree that for command line applications the above options are best.
 
Hey Andersod2,

You seem like someone who might know- I'm building an app with Qt, I've got it working on my mac, but when I try to compile it on winXP I get a couple of errors from hidclass.h:

"cannot declare field "_HID_INTERFACE_HIDPARSE::i to be of abstract type 'IPrintDialogServices"

"cannot declare field "_HID_INTERFACE_NOTIFY_PNP:: (same error as above)"


...the headers that are included with the minGW in Qt 5.3 are slightly different- hidsdi.h is located one up from /ddk in /include, and there is another header that seems to matter, hidusage.h.

Can't quite figure it out. Any insight, much appreciated.
 
I'm trying to follow the instructions for building a windows binary using Qt on a mac with Qt 4.8.2. I like the idea of a standalone executable, which this setup builds...seems also 4.8.2 has the same library/ include structure as what's required for Paul's HID code. I'll let you all know how it goes.
 
glasspusher,
This seems a bit off topic, so feel free to send me a personal message on the site instead of discussing here on the thread, or start a new thread. In short, though, errors like this can come up with platform dependency i.e. compiler differences - requiring certain C++ rules to be followed on one compiler but not another. Have you gotten anything to compile with the hid stuff on mingw? I would start there with a basic hello world, then start comparing what header files have been picked up by your qt project that aren't in the basic project. Mingw worked out of the box for me with the hid stuff, but I haven't tried on winxp I don't think (but I think that is supported). I would pay special attention to any compiler switch differences or project include paths that are different on your qt project (than from a basic project).
 
Hey all,

Thought I'd post to answer my own question: Qt wanted a -lhid as well as -lsetupAPI in the .pro file

LIBS += -lhid -lsetupAPI

I've got it building for windows on my mac with Qt 4.8, I'm going to play around and see if I can get it to build with Qt 5.3 on the windows machine. There is a slight re-shuffling of stuff in the headers between the versions of mingw that these two versions of Qt use.
 
I Apologize for the necro, but...

I took what AMandersod2 added and created a few extra exported functions. They store the PID/VID/Usage/UsagePage in the HID structure. This lets me cherry pick a HID. I can write a calling function that looks up the PID based on an index value.

I also wrote some AutoHotkey functions to call the DLL.

Code:
;{ Start - Start the HID interface
RawHidStart()
{
	global hHidModule
	
	; Load the DLL
	hHidModule := DllCall("LoadLibrary", "Str", "rawhid.dll", "Ptr")  ; Avoids the need for DllCall() in the loop to load the library.
}
;}

;{ RawHidOpen - Open one or more HID interfaces
RawHidOpen(vPid := -1, vVid := 0xFEED, vUsagePage := 0xFF31, vUsage := 0x74)
{
	global hHidModule, vNumberOfRawHids
	vCount := 999

	vNumberOfRawHids := DllCall("rawhid.dll\rawhid_open@20", "Int", vCount, "Int", vVid, "Int", vPid, "Int", vUsagePage, "Int", vUsage)
	if ErrorLevel
	{
		MsgBox, Could not load rawhid.dll\rawhid_open@20 (Error = %ErrorLevel%)
		vNumberOfRawHids := -1
	}
	return vNumberOfRawHids
}
;}

;{ RawHidGetPid - Get PID
RawHidGetPid(vHidIndex)
{
	vPid := DllCall("rawhid\rawhid_get_pid@4", "Int", vHidIndex)
	if ErrorLevel
	{
		MsgBox, Could not load rawhid.dll\rawhid_get_pid@4 (Error = %ErrorLevel%)
		vPid := 0
	}
	return vPid
}
;}

;{ RawHidGetPid - Get PID
RawHidRead(vHidIndex, vTimeout)
{
	; Buffersize must be greater than 32 or else the DLL call will fail. This is because the size of the RawHID packet 
	; (CONSOLE_EPSIZE) is 32.
	vHidBufferSize := 32
	VarSetCapacity(vHidBuffer, vHidBufferSize + 1, 0)
	; rawhid_recv(int num, void *buf, int len, int timeout)
	vCount := DllCall("rawhid\rawhid_recv@16", "Int", vHidIndex, "UPtr", &vHidBuffer, "Int", vHidBufferSize, "Int", vTimeout)
	if ErrorLevel
	{
		MsgBox, Could not load rawhid.dll\rawhid_recv@16 (Error = %ErrorLevel%)
		vHidBuffer := ""
	}
	if (vCount > 0)	
	{
	VarSetCapacity(vHidBuffer, -1)
	DbgMsg("Count = " . vCount .  ", Buffer = <" . vHidBuffer . ">")	
	}
	return vHidBuffer
}
;}

;{ RawHidGetIndexByPid - Get the HID Index based on the PID
RawHidGetIndexByPid(vPid)
{
	global vNumberOfRawHids
	Loop, %vNumberOfRawHids%
	{
		vHidIndex := A_Index - 1
		vCurrentPid := RawHidGetPid(vHidIndex)
		if (vCurrentPid == vPid)
		{
			return vHidIndex
		}
	}
	return -1
}
;}

;{ RawHidClose - Close one or more HID Interfaces
RawHidClose(vHidIndex := -1)
{
	global vNumberOfRawHids

	if (vHidIndex < 0)
	{
		Loop, %vNumberOfRawHids%
		{
			DllCall("rawhid\rawhid_close@4", "Int", A_Index-1)
			if ErrorLevel   
			{
				MsgBox, Could not load rawhid.dll\rawhid_close@4 (Error = %ErrorLevel%)
			}
		}
	}
	else
	{
		DllCall("rawhid\rawhid_close@4", "Int", vHidIndex)
		if ErrorLevel   
		{
			MsgBox, Could not load rawhid.dll\rawhid_close@4 (Error = %ErrorLevel%)
		}
	}
}
;}

;{ RawHidStop - Stop the HID Interface
RawHidStop()
{
		global hHidModule
		RawHidClose()
		DllCall("FreeLibrary", "Ptr", hHidModule)  ; To conserve memory, the DLL may be unloaded after using it.
}
;}
 

Attachments

  • rawhid_dll_and_source.zip
    17.1 KB · Views: 255
Things have improved a lot. Microsoft has cleaned up the DDK and I'm able to compile the HID stuff with standard Visual Studio 2013 and 2015 installations. Mingw-w64 also works fine.

In terms of Autohotkey, standard Windows raw input also works:
https://github.com/jleb/AHKHID

Device connects/disconnects/reconnects are transparently handled. The input events include vendor id, product id, usage page and usage.


There is a memory leak in rawhid_open:
https://forum.pjrc.com/threads/36745-Memory-leak-in-Windows-rawhid-sample-code
 
Things have improved a lot. Microsoft has cleaned up the DDK and I'm able to compile the HID stuff with standard Visual Studio 2013 and 2015 installations. Mingw-w64 also works fine.

In terms of Autohotkey, standard Windows raw input also works:
https://github.com/jleb/AHKHID

Device connects/disconnects/reconnects are transparently handled. The input events include vendor id, product id, usage page and usage.

There is a memory leak in rawhid_open:
https://forum.pjrc.com/threads/36745-Memory-leak-in-Windows-rawhid-sample-code

Thanks for the tip on the memory leak.

I was looking at RawHid over the AHKHID wrapper because I wanted to also send data (and have a more flexible language independent method of communication).
 
Back
Top