Create a VC++ DLL in Visual Studio 2012 for mIRC with CUDA
Requirements:
- Visual Studio 2012 (Not Community)
- CUDA Toolkit v7.5 https://developer.nvidia.com/cuda-toolkit
For a build in VS 2013 Community, please reference
https://github.com/mryanbrown/mCUDA
Note: Install VS before CUDA toolkit.

Create New Project File . . .

Installed > Templates > Visual C++ > Win32 > Create Win32 Project
Name your Project (ie: myDLL)
Press "OK"

Check (x) DLL
Check [x] Empty Project

Right Click your solution workspace name "myDLL"
Click "Properties"

Change "Character Set" to "Use Multi-Byte Character Set"
Note: for CUDA to work, the "Platform Toolset" should be v110 which is
why we're using VS2012.

In the same properties menu, navigate down to
"VC++ Directories" and ensure the following directories are included:
Include Directories:
$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5\common\inc\;
$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5\common\lib\;

Navigate to Linker > General > Additional Library Directories:
%(AdditionalLibraryDirectories);$(CudaToolkitLibDir);$(CUDA_LIB_PATH);C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5\common\lib\;

Navigate to Linker > Input
Add "cudart.lib" to the beginning, so it looks like this:
cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
Apply these settings and press "OK"

Right Click your solution workspace "myDLL"
Navigate to "Build Customizations..."

Now to add the CUDA dependancies click [X] CUDA 7.5(.targets, .props)
Press "OK"

Right click your solutions "Source Code" section
Click Add > New Item...

Navigate to "NVIDIA CUDA 7.5" > Code
Select "CUDA C/C++ File"
Name it, the same as your DLL name. (ie: myDLL)
Press "Add"

Right click your solutions "Source Files" section.
Click Add > New Item...

Navigate to Installed > Visual C++ > Code
Select "Module-Definition File (.def)
Name it, the same as your DLL name. (ie: myDLL)
Press "Add"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#include <cuda_runtime.h>
#include <helper_functions.h>
#include <helper_cuda.h>
using namespace std;
typedef struct {
DWORD mVersion; //!< mIRC Version
HWND mHwnd; //!< mIRC Hwnd
BOOL mKeep; //!< mIRC variable stating to keep DLL in memory
} LOADINFO;
typedef struct {
HANDLE m_hFileMap; //!< Handle to the mIRC DLL File Map
LPSTR m_pData; //!< Pointer to a character buffer of size 900 to send mIRC custom commands
HWND m_mIRCHWND; //!< mIRC Window Handle
} mIRCDLL;
mIRCDLL mIRCLink;
void WINAPI LoadDll(LOADINFO * load) {
mIRCLink.m_hFileMap = CreateFileMapping( INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 4096, "mIRC" );
mIRCLink.m_pData = (LPSTR) MapViewOfFile( mIRCLink.m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
mIRCLink.m_mIRCHWND = load->mHwnd;
}
int WINAPI UnloadDll( int timeout ) {
// DLL unloaded because mIRC exits or /dll -u used
if ( timeout == 0 ) {
UnmapViewOfFile( mIRCLink.m_pData );
CloseHandle( mIRCLink.m_hFileMap );
return 1;
}
// Keep DLL In Memory
else
return 0;
}
int __declspec(dllexport) __stdcall cudaCard(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) {
int nDevices;
string str = "";
cudaGetDeviceCount(&nDevices);
for (int i = 0; i < nDevices; i++) {
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, i);
str = str + prop.name + " @" ;
}
char *cstr = &str[0u];
strcpy(data, cstr);
return 3;
}
LIBRARY myDLL
EXPORTS
cudaCard
LoadDll
UnloadDll
Build Solution (F7) or Rebuild Solution.
Your output should look similar.

Open mIRC and test the DLL.
with //echo -a $dll(myDLL.dll,cudaCard,$null)
the DLL will remain loaded until you unload it with /dll -u myDLL.dll
Note:
I did have one compile where the "Build Succeeded" however there was no DLL file.
and my lastbuildstate kept showing up. #v4.0:v110:false
What I did to reset it was:
- Remove the .CU file.
- Add a regular VC++ CPP file.
(using the same code that was in the .CU) - Compile.
- Add a .CU file again (with same code).
- Compile again (with CPP file)
- Delete .CPP file from the project.
That worked for me. Let me know if you have issues.
Another thing, this is a 32-bit DLL, that means that CUDA has to compile in 32-bit mode.
I have not tested the extent of the limitations, but from what I have read there are some.
I tried a 64-bit Compile and mIRC didn't recognize it. I did read that mIRC has been
porting a lot of its code over in expectations to becoming 64-bit, so perhaps it might not
be too long before it might be accepted.
Update December 2, 2015
* Added new code to prevent mIRC from freezing when too many calls are made to it.
Simply call the $dll(myDLL,noFreeze) to enable/disable this feature.



