I've never used C++ in Visual Studio but do some work with C# and VB.
I have a simple x86 C++ project that loads a 32bit DLL then uses a function from it.
It was working fine, then I changed some settings (SDK version, toolset, C++ language standard) and now I get "The specified module could not be found." when I try and load the DLL.
I've reset C++ in the "Import and export settings wizard" and then reinstalled all of Visual Studio but I can't seem to find a way to get the project back to working with this DLL. Dumpbin shows me that all the dependencies it needs are in SYSWOW64 :/
I've made copies of the DLL and put them everywhere I can think of, but I get the same problem. It loads with C# but I have some memory access issues passing strings to one of the functions.
Anyone had an issue like this before?
//Get current exe path and add DLL filename.
char cDLLPath[MAX_PATH + 1];
TCHAR bufCurrentDirectory[MAX_PATH + 1] = { 0 };
DWORD dwNumCharacters = ::GetCurrentDirectory(MAX_PATH, bufCurrentDirectory);
if (dwNumCharacters == 0)
{
printf("Error getting executable path\n");
exit(0);
}
snprintf(cDLLPath, MAX_PATH + 1, "%s\\MyDLL.dll", bufCurrentDirectory);
HINSTANCE myDll = LoadLibrary((LPCWSTR)cDLLPath);
//MyDLL is always NULL, error message is always "The specified module could not be found."
I've removed the path, tried current working folder, moved it to c:\windows\system32 etc
This function tells me the DLL path\filename are correct.
BOOL file_exists(const fs::path& file_path, fs::file_status s = fs::file_status{})
{
if (fs::status_known(s) ? fs::exists(s) : fs::exists(file_path)) return true;
else return false;
}
-Pook
Related
Problem Description
I have an application that loads a dll at runtime. I want to allow a user to change code in that dll while the app is running. When the user clicks the "compile" button in the app it would free all the data from the dll. After freeing up the dll the app would then rebuild the dll. Essentially acting as a
Run time compiled program.
Ideal Implementation
void ReCompile()
{
//hDLL contains dll that was already loaded.
FreeLibrary(hDLL);
//code to rebuild MyDll.DLL would go here.
LPCWSTR dll = L"MyDll.dll";
hDLL = LoadLibrary(dll);
}
This currently works i just need to know how to rebuild the dll through code so it feels much more smooth and intuitive.
Current Implementation
void Free()
{
FreeLibrary(hDLL);
}
//I go into my other visual studio that's running and press the build button myself.
void ReloadDll()
{
LPCWSTR dll = L"MyDll.dll";
hDLL = LoadLibrary(dll);
}
Credit goes to TheUndeadFish.
void ReCompile()
{
//hDLL contains dll that was already loaded.
FreeLibrary(hDLL);
//my solution
system("msbuild \"D:\\Neumont\\Imagine\\RenderEngine\\Imagine.sln\" /property:Configuration=Debug /property:platform=Win32 ");
//general purpose
system("msbuild <path to your sln> /property:Configuration=build /property:platform=YourPlatform");
LPCWSTR dll = L"MyDll.dll";
hDLL = LoadLibrary(dll);
}
You need to add msbuild path to your enviorment variables. Mine was located in C:\Program Files (x86)\MSBuild\14.0\Bin. you might have to run vcvars32.bat
video of building DLL at runtime in action https://youtu.be/mFSv0tf6Vwc
I'm trying to write a simple SGX project for a start. So I have this main host application routine that I've pretty much copied from Lars Richter's blog:
#define ENCLAVE_FILE _T("Enclave.signed.dll")
#include <tchar.h>
#include <cstdio>
#include "sgx_urts.h"
#include "Enclave_u.h"
int main()
{
sgx_enclave_id_t eid;
sgx_status_t ret = SGX_SUCCESS;
sgx_launch_token_t token = { 0 };
int updated = 0;
ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
if (ret != SGX_SUCCESS) {
printf("\nApp: error %#x, failed to create enclave.\n", ret);
}
scanf("\n");
return 0;
}
It compiles fine (I'm using the Intel C++ 17.0 compiler with Visual Studio 2015) but it doesn't load the enclave. I get the following error message:
[sgx_create_enclavew ..\urts\win\urts.cpp:195] Couldn't open file with CreateFile()
App: error 0x200f, failed to create enclave.
Go to app_test_save project setting. Under Debugging, change working directory to $(SolutionDir)Debug. This answer assumes that both projects app_test_save and enclave_test_save belong to the same solution.
As Neil pointed out, sgx_create_enclave couldn't find the dll when the program was being run from within Visual Studio's debugger. It worked fine when I directly ran the executable in the "Debug" folder.
So a simple trick to make it work in both settings is to do the following:
#define ENCLAVE_FILE _T("../Debug/Enclave.signed.dll")
According to this : https://software.intel.com/en-us/forums/intel-software-guard-extensions-intel-sgx/topic/623738
If you are using the Local SGX Debugger, Please make sure change the "current working directory" pointing to $(OutDir) instead of $(ProjectDir).
Configuration Properties --> Debugging --> Working Directory --> $(OutDir).
Error is basically means it could not locate your .dll file.
Do dir /a/s to find Enclave.signed.dll then change the name appropriately.
When you create enclave it will generate signed.dll file. If your enclave name is Enclave12 then the DLL name is Enclave12.signed.dll. You fix this then you should be good to go.
I have created VC++ Dll in Visual Studio 2013.
extern "C" int __declspec(dllexport) __cdecl ConvertImageToText(char* dataPath, char* imageFilePath, char* captchaCode)
{
// to do
return 0;
}
I'm using in Borland C++ Builder 6 like that.
HMODULE dllHandle = LoadLibrary("Captcha.dll");
int (__cdecl *ConvertImageToText)(char*,char*,char*);
ConvertImageToText =(int (__cdecl *)(char*,char*,char*))GetProcAddress(dllHandle, "ConvertImageToText");
if (ConvertImageToText != NULL )
{
ConvertImageToText("","","");
}else
{
ShowMessage("ConvertImageToText pointer not found !");
}
it's working well in win7/8/8.1.there isn't any problem.
But can't find pointer of ConvertImageToText on windows xp sp3.
I have changed VC++ Dll Project "Platform Toolset" as "Visual Studio 2013 - Windows XP (v120_xp)".nothing not changed.
I have checked Visual C++ Redistributable packages.All installed
Any sugguestions ?
You need to implement proper error checking as described by the documentation.
Test the return value of LoadLibrary. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
E. Test the return value of GetProcAddress. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
Likely LoadLibrary is failing because your DLL is linked to a runtime that is not installed on the target machine, or because your DLL is linked to Win32 API functions that do not exist on XP.
If you cannot work it out from here you can use Dependency Walker for extra debugging. Use it in profile mode to debug the loader's attempt to load the DLL. That will reveal enough information to diagnose the problem.
I have installed that redist release. it worked.
I'm using SQL2012 and VS2012.
I'd like to implement this solution for watching a file's date and time stamp which is updated by a dll when a trigger on a SQL table is fired.
Here is what I'm trying to do.
Which references a MSDN article
I’ve followed the instructions but got this:
Msg 17750, Level 16, State 0, Procedure xsp_UpdateSignalFile, Line 1
Could not load the DLL XSP.dll, or one of the DLLs it references. Reason: 193(%1 is not a valid Win32 application.).
I’m assuming because I’m using SQL2012 64-bit.
I downloaded the XSP.DLL source and looking at in the VS2012 but can’t get it to compile, even after finding myself a copy of opends60.lib
Error 4 error LNK2019: unresolved external symbol _srv_rpcparams referenced in function _xsp_UpdateSignalFile C:\Users\Administrator\Documents\xsp.dll\WickedCode0304\XSP\XSP.obj XSP
Can a C++ wizard help me compile this to 64bit or am I going wrong earlier?
It is saying it can't resolve some received params?
The .cpp file looks like this:
#include <windows.h>
#include <srv.h>
///////////////////////////////////////////////////////////////////////
// Entry point
extern "C" BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD dwReason,
LPVOID lpReserved)
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////
// Exported functions
extern "C" __declspec (dllexport)
ULONG __GetXpVersion ()
{
return ODS_VERSION;
}
extern "C" __declspec (dllexport)
SRVRETCODE xsp_UpdateSignalFile (SRV_PROC *srvproc)
{
//
// Make sure an input parameter is present.
//
if (srv_rpcparams (srvproc) == 0)
return -1;
//
// Extract the file name from the input parameter.
//
BYTE bType;
char file[256];
ULONG ulMaxLen = sizeof (file);
ULONG ulActualLen;
BOOL fNull;
if (srv_paraminfo (srvproc, 1, &bType, &ulMaxLen, &ulActualLen,
(BYTE*) file, &fNull) == FAIL)
return -1;
if (bType != SRVBIGCHAR && bType != SRVBIGVARCHAR)
return -1;
file[ulActualLen] = 0;
//
// Update the file's time stamp.
//
char path[288] = "C:\\AspNetSql\\";
lstrcat (path, file);
HANDLE hFile = CreateFile (path, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle (hFile);
return 0;
}
I got this working with using SQL Server 2008 SP3 Dev 64-bit and VS 2012 Ultimate running on Win 7 Pro 64-bit. Here's what I did:
Created a new Empty Project from the VC++templates in VS and added an empty C++ file.
Changed platform to x64 in the Configuration manager.
Changed the Configuration Type to Dynamic library (.dll) under Configuration Properties/General.
Installed the SQL x64 native client including the SQL Server Native Client SDK to get the opends60.lib. I'm not sure the SDK component is actually needed.
Added C:\Program Files\Microsoft SQL Server\90\SDK\Lib\x64 to Additional library directories in the Linker options. This was were the native client was installed.
Added opends60.lib to Additional dependencies in the Linker options.
Compiled without errors.
Created the output directory that the XSP.dll uses: C:\AspNetSql\.
Copied the XSP.dll to the directory created in step 8.
Installed the extended stored procedure using:
USE master
EXEC sp_addextendedproc 'xsp_UpdateSignalFile', 'C:\AspNetSql\XSP.dll'
GRANT EXECUTE ON xsp_UpdateSignalFile TO PUBLIC
Executed it using master..xsp_UpdateSignalFile 'Quotes.Quotations'and verified it worked by confirming that the file Quotes.Quotations was created in the output directory.
If you have any questions or want clarification on any step I can add screenshots or provide more information.
I am working on some video editing software and need to use some Direct3D components to improve performance. Specifically, I need to use the MFCreateDXSurfaceBuffer function to create samples from a direct3d surface. After adding code to use this function, I get the following message when trying to run the compiled executable:
The procdedure entry point MFCreateDXSurfaceBuffer could not be located in the dynamic link library MFPlat.dll
Output window: The program '[0x1C04] ClassLibrary1.exe: Native' has exited with code -1073741511 (0xc0000139) 'Entry Point Not Found'.
I created a minimalistic project that reproduces the problem:
#include < mfapi.h >
#include < d3d9.h >
#include < evr.h >
static void
Fail
(
)
{
IDirect3DSurface9* theSurface = nullptr;
IMFMediaBuffer* theBuffer = nullptr;
MFCreateDXSurfaceBuffer(__uuidof(IDirect3DSurface9), theSurface, FALSE, &theBuffer);
}
int main()
{
Fail();
}
I added "evr.lib;mfplat.lib;D3d9.lib" to Properties->Linker->Input Additional dependencies
I am using:
Windows 7 64 bit
MS Visual Studio 2012
C++
What I've tried:
Google - no mention of a similar problem
Ran the code on a co worker's machine. Same issue occurs.
Call other functions from evr.dll. Some work, some have the same problem
Dependency Walker: mini project EXE Depends on MFPLAT.DLL, MSVCR110D.DLL and KERNEL32.DLL.
Error message:
"At least one module has an unresolved import due to a missing export function in an implicitly dependent module."
Obviously, the function that did not import was MFCreateDXSurfaceBuffer.
You may have noticed that MFCreateDXSurfaceBuffer is defined EVR.dll, which is conspicuously absent from my dependency list.
Why is the function failing to import and how do I fix it?
The procdedure entry point MFCreateDXSurfaceBuffer could not be located in the dynamic link library MFPlat.dll
MFCreateDXSurfaceBuffer function is exported off evr.dll, not mfplat.dll - you already discovered this. I suppose you might be using some wrong/corrupt Windows SDK version. At least with Windows SDK 7.0 the code builds and starts fine. Besides the code snippet quoted above you only need to add evr.lib as additional linker input.
I'm also facing this issue.
For the record, I'm writing the solution I found here :
HMODULE evrModule = LoadLibraryA("evr.dll");
/* MFCreateDXSurfaceBuffer prototype */
typedef HRESULT(STDAPICALLTYPE *MFCDXSB)(_In_ REFIID iid, _In_ IUnknown *unkSurface, _In_ BOOL bottomUpWhenLinera, _Out_ IMFMediaBuffer **mediaBuffer);
MFCDXSB pMFCreateDXSurfaceBuffer = (MFCDXSB)GetProcAddress(evrModule, "MFCreateDXSurfaceBuffer");
Do not forget to check for errors and to call FreeLibrary(evrModule) at the end
I tried several things and they all failed. I know this is a bit hardcore but at least it works and I only do this for this method so I guess it's ok.
After coming across this problem, I searched the library files in the Windows SDK directory and found a .lib file that exports the MFCreateDXSurfaceBuffer function. The file is called evr_vista.lib.
I have no clue why EVR functions have been split into the evr.lib and evr_vista.lib.
Adding "evr_vista.lib" in addition to "evr.lib" to the list of libraries to link with should resolve any linking errors.
Under Visual Studio:
Project Properties > Configuration Properties > Linker > Input > Additional Dependencies