#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <dos.h>
using namespace std;
class Dir
{
public:
char* cat;
Dir()
{
cout << "(C:/*)\n";
cat = new char[50];
cin >> cat;
}
void virtual ShowFiles()
{
}
};
class Inside : public Dir
{
public:
void virtual ShowFiles()
{
HANDLE hSearch;
WIN32_FIND_DATA pFileData;
hSearch = FindFirstFile(cat, &pFileData);
if (hSearch != INVALID_HANDLE_VALUE)
do
{
// if ((pFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
cout << pFileData.cFileName << "\n";
} while (FindNextFile(hSearch, &pFileData));
FindClose(hSearch);
}
};
int main()
{
Dir *obj1[2];
obj1[1] = new Inside;
obj1[1]->ShowFiles();
return 0;
}
So I have a program, I need to show with dynamic char cat all file in directory, but it is compilable in Borland C++ but in Visual Studio 15 + Resharper it doesn't work. Severity Code Description Project File Line
Error (active) argument of type "char *" is incompatible with parameter of type "LPCWSTR"
To compile your code in Visual C++ you need to use Multi-Byte char WinAPI functions instead of Wide char ones.
Set Project -> Properties -> Advanced (or. General for older versions) -> Character Set option to Use Multi-Byte Character Set
also see the screenshot
I actually found another way to resolve this error since above method did not work for me.
I casted all my constant character strings with (LPCWSTR). The solution looks like this
Earlier
MessageBox(NULL,"Dialog creation failed! Aborting..", "Error", MB_OK);
After casting to LPCWSTR
MessageBox(NULL, (LPCWSTR) "Dialog creation failed! Aborting..", (LPCWSTR) "Error", MB_OK);
So just copying the (LPCWSTR) and pasting wherever this error was generated resolved all my errors.
Another way to come by this issue, is to use the Lmacro in front of your string.
MessageBox(NULL, L"Dialog creation failed! Aborting..", L"Error", MB_OK);
See: What does the 'L' in front a string mean in C++?
or
L prefix for strings in C++
you can use wchar_t
class Dir
{
public:
wchar_t* cat;
Dir()
{
wcout << "(C:/*)\n";
cat = new wchar_t[50];
wcin >> cat;
}
void virtual ShowFiles()
{
}
};
In Visual Studio 2013 and later, the MFC libraries for multi-byle character encoding (MBCS) will be provided as an add-on to Visual Studio
It will work for any settings:
#include <tchar.h>
MessageBox(NULL, _T("Dialog creation failed! Aborting.."), _T("Error"), MB_OK);
Related
Can someone provide insight when to use _Notnull_? I'm using Visual Studio 2019 and here is my code:
#include <windows.h>
#include <vector>
void WriteIt(_Notnull_ CONST WCHAR* sMsg, _Notnull_ CONST WCHAR* sFileName)
{
FILE* stream;
errno_t err = _wfopen_s(&stream, sFileName, L"a+");
if (err == 0)
if (stream)
{
fwprintf_s(stream, L"%s", sMsg);
fclose(stream);
}
}
int main()
{
WCHAR *sMessage = new WCHAR[16]();
WCHAR *sFile = NULL;
sFile = NULL;
WriteIt(sMessage, sFile);
}
Yet, the _Notnull_ lets the function run. I can't find any documentation on how/why to use it with examples.
Thanks #François Andrieux. Looks like it is used when doing a code analysis from within Visual Studio, where the analyzer can pinpoint if an incoming pointer could be NULL. Here is what the code analyzer says with _Notnull_ is included: Warning C6387 'sFile' could be '0': this does not adhere to the specification for the function 'WriteIt'. Very helpful!
I'm building a new project in Visual Studio 2019. It's a console app that includes MFC headers. Here's the relevant code:
int main(int argc, TCHAR* argv[]) // VS wrote "int main()", I added parameters myself.
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: code your application's behavior here.
wprintf(L"Fatal Error: MFC initialization failed\n");
nRetCode = 1;
}
else
{
nRetCode = MyFunction(argc, argv);
}
}
else
{
// TODO: change error code to suit your needs
wprintf(L"Fatal Error: GetModuleHandle failed\n");
nRetCode = 1;
}
return nRetCode;
}
Most of this is boilerplate code generates by VS. I added parameters to the main function and the call to my own code, namely MyFunction(). It built just fine; didn't issue so much as a warning. On the very first test run I found that the text in argv[1] and argv[2] are in plain 8-bit ASCII or UTF-8. I was expecting UNICODE as UTF-16LE.I do have the project properties set to use UNICODE. What have I done wrong to get command line parameters in UTF-8? Here's my setup in VS 2019:
My OS is Windows 10.
main() only works with char in the argv[] array. If you want to use wchar_t instead, you need to rename main() to wmain() instead.
Or, since you are using TCHAR, you can rename main() to _tmain(), so that it will automatically map to main() in a MBCS build, and to wmain() in a Unicode build. See What is difference between main and _tmain in Visual studio
For some reason I can no longer compile a c file in my c++ clr console application. It worked before without the clr support, I also switched my project to compile as /TP still not working. Any help would be greatly appreciated.
Error
Severity Code Description Project File Line Suppression State
Error C2664 'int strcmp(const char *,const char *)': cannot convert argument 1 from 'WCHAR [260]' to 'const char *'
snowkill.c
#include "snowkill.h"
void killProcessByName(WCHAR *filename)
{
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(pEntry);
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes)
{
if (strcmp(pEntry.szExeFile, filename) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
(DWORD)pEntry.th32ProcessID);
if (hProcess != NULL && pEntry.th32ProcessID != GetCurrentProcessId())
{
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
}
snowkill.h
#pragma once
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void killProcessByName(WCHAR *filename);
#ifdef __cplusplus
}
#endif
main.cpp
#include "stdafx.h"
#include "snowkill.h"
#include "motion.h"
#include "info.h"
#include "flushsound.h"
#include "snowserial.h"
using namespace System;
bool on() {
return true;
}
bool off() {
return false;
}
int main()
{
listenoncommport();
for (;;) {
string onoff = checkfile();
if (onoff == "1")
{
//detected();
}
else
{
WCHAR *proccc = L"firefox.exe";
killProcessByName(proccc);
//notdetected();
}
Sleep(5000);
}
return 0;
}
You could change every instance of WCHAR to TCHAR so text setting is "generic", or as already mentioned, change the project property character set to be Unicode only.
void killProcessByName(TCHAR *filename)
/* ... */
if (_tcscmp(pEntry.szExeFile, filename) == 0) /* replaced strcmp */
/* ... */
#include <windows.h> /* needed in order to use TEXT() macro */
/* ... */
TCHAR *proccc = TEXT("firefox.exe"); /* TEXT() is a <windows.h> macro */
Use TCHAR type everywhere if the functions involved are not WCHAR specific. That would allow project setting to build either ANSI/ASCII (not set) or Unicode.
Note that Process32First and Process32Next use TCHAR.
This is mostly for legacy, since Windows 2000 and later API functions use Unicode internally, converting ANSI/ASCII to Unicode as needed, while Windows NT and older API functions use ANSI/ASCII.
However, typically many or most text files (such as source code) are ANSI/ASCII and not Unicode, and it's awkward to have to support Unicode for Windows API and then ANSI/ASCII for text files in the same program, and for those projects I use ANSI/ASCII.
By using the TCHAR based generic types, I can share common code with projects that use Unicode and with projects that use ANSI/ASCII.
The error message is clear: you have an error at this precise line:
if (strcmp(pEntry.szExeFile, filename) == 0)
Because your arguments are not of char* type as expected by strcmp but WCHAR* types. You should use wcscmp instead, which is basically the same function, but working with wchar_t* type.
szExeFile in tagPROCESSENTRY32 is declared as TCHAR, which will be a 1-byte char when compiling with Character Set set to 'Not Set' or 'Multibyte'. Set Character Set in your project settings to Use Unicode Character Set to fix the problem.
Also, use wcscmp to compare WCHAR types.
guys whay i have this to error and how i can fix that?!
but before that i say i searched in the net and find a solution for my problem such as:
the properties, and navigate to Configuration Properties > General. Switch Character Set to "Use Multi-Byte Character Set".
but also i have same error?!!
The error's:
Error 7 error C2664: 'MessageBoxA' : cannot convert parameter 2 from 'const wchar_t [58]' to 'LPCSTR'
Error 8 error C2664: 'int std::basic_string<_Elem,_Traits,_Ax>::compare(const std::basic_string<_Elem,_Traits,_Ax> &) const' : cannot convert parameter 1 from 'CHAR [260]' to 'const std::basic_string<_Elem,_Traits,_Ax> &'
and my code is:
#include "StdInc.h"
#include<fstream>
#include<sstream>
#include<string>
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<Windows.h>
#include<TlHelp32.h>
using std::ifstream;
using std::string;
using std::getline;
using std::ios;
using std::cerr;
using std::cout;
using std::endl;
using std::fixed;
using std::left;
using std::right;
using std::showpoint;
using std::cin;
class check {
public :
void check_seta () {
ifstream cfgm2("finfin.cfg",ios::in);
string cfgLine;
while (getline(cfgm2,cfgLine)) {
if (string::npos != cfgLine.find("seta mamamia")){
if (cfgLine.at(19) == '0'){
MessageBox(NULL , L"lol not do that",NULL,MB_ICONERROR);
std::wstring Processname(L"mod.exe");
DWORD ProcessId = FindProcessId(Processname);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE ,ProcessId);
TerminateProcess(pHandle,0);
CloseHandle(pHandle);
}
break;
}
}
}
DWORD FindProcessId(const std::wstring& processName)
{
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( processesSnapshot == INVALID_HANDLE_VALUE )
return 0;
Process32First(processesSnapshot, &processInfo);
if ( !processName.compare(processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while ( Process32Next(processesSnapshot, &processInfo) )
{
if ( !processName.compare(processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
};
In the project settings you did not select Unicode. So you have the narrow sharacter version of the WIN32 API. MessageBox maps to MessageBoxA, and the process info structure has LPCSTR in it. If you change the setting those become MessageBoxW and LPCWSTR, and the code will compile (or you get other errors elsewhere).
If you mean to use that the A versions, use char instead of wchar_t, string instead of wstring, "xxx" instead of L"xxxx" all around.
You're using wide string literals (L"..."), so you must actually use the Unicode character set in the Project settings you mention. This will define _UNICODE and make all Windows function-name macros expand to the wide-character variants (suffix W).
Or, preferably, if you know you want to use wide strings, just call the wide-char versions directly. That is, use MessageBoxW instead of MessageBox, etc. for other char-width-specific functions.
In your project properties in Visual Studio, go to Configuration Settings > C/C++ > Preprocessor > Preprocessor Definitions and make sure UNICODE; is defined. That fixed a similar error for me.
I have a problem I've been struggeling with for a full week now, and I'm not able to solve it by myself. I've been googeling, and searching in all kind of forums... I have found lots of "this might work", tried it, but no, no success. If anyone have any clue, please, please, help me!
I'v got, from an external source, lots of classes and functions written in VB that I need to be able to use from a C++ application. My first though was: no problem, I turn the VB code into a dll, and load it from my C++-program. This was though harder than I ever could imagine. My C++-program is not written in Visual Studio, but for simplicity I started with trying to load my VB dll (written in Visual Studio 2010) from a Visual Studio C++ application. This is my code so far:
VB-code : DllModule : Class-library project
DllModule.vb
Namespace DllModule
Public Module DllModule
Public Const DLL_PROCESS_DETACH = 0
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3
Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long,
ByVal lpvReserved As Long) As Boolean
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
DllMain = True
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
Return True
End Function
'Simple function
Public Function Add(ByVal first As Integer, ByVal sec As Integer) As Integer
Dim abc As Integer
abc = first + sec
Return abc
End Function
End Module
End Namespace
DllModule.def
NAME DllModule
LIBRARY DllModule
DESCRIPTION "My dll"
EXPORTS DllMain #1
Add #2
C++-code : TryVbDllLoad : Console application
TryVbDllLoad.cpp
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <strsafe.h>
extern "C" {
__declspec(dllimport) int __stdcall Add(int, int);
}
typedef int (__stdcall *ptf_test_func_1_type)(int, int);
int __cdecl _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hdll = NULL;
hdll = LoadLibrary("DllModule.dll"); // load the dll
if(hdll) {
ptf_test_func_1_type p_func1=(ptf_test_func_1_type)GetProcAddress(hdll,"Add");
if(p_func1) {
int ret_val = (*p_func1)(1, 2);
} else {
DWORD dw = GetLastError();
}
FreeLibrary(hdll); // free the dll
} else {
DWORD dw = GetLastError();
}
return 0;
}
I can load the dll, but GetProcAddess returns NULL with error code 127 (the specified procedure could not be found).
I have tried to load the dll from a VB-application. This works (even without the .def-file). But I'm guessing there is no proper entry point created that the C++ application can use (when I open the dll in Dependency Walker I see no entry point or functions). I've tried compiling the VB-code both with and without "Register for COM interop".
1) What am I doing wrong?
2) If there isn't any nice way to solve this properly, what can I do instead of creating a dll? Is there any other way I can use the VB-classes and functions in my C++ application?
Kind Regards
Sara
Thanks for your answer Mare!
There must be some kind of error in my dll though, cause when I try to register is using regsvr32 I get: "The module C:/tmp/DllModule.dll was loaded, but the start address for DllRegisterServer was not found. Check that C:/tmp/DllModule.dll is a valid DLL- or OCX-file and try again."
Also, when I use
#import "C\tmp\DllModule.dll"
I get
fatal error C1083: Cannot open type library file: 'c:\tmp\dllmodule.dll'
I looked at the link with the tutorial, but there is a small problem: there are no such thing as "ActiveX DLL" to choose among all the project types. And yes, I do have Visual Studio 2010 Professional (a trial version, but still).
-- Sara
Thanks for all the input. I've come across another way to solve my problem, using a multifile assembly rather than my first dll approach.
I followed this HowTo-section: http://msdn.microsoft.com/en-us/library/226t7yxe.aspx#Y749
VB-code : DllModule : Class-library project
DllModule.vb
Imports System.Runtime.InteropServices
Namespace DllModuleNS
Public Class Class1
Public Function ClassAdd(ByRef first As Integer, ByRef sec As Integer) As Integer
Dim abc As Integer
abc = first + sec
Return abc
End Function
End Class
End Namespace
This file I compiled using both visual studio (to produce DllModule.dll-file) and cmd-line:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Vbc.exe /t:module DllModule.vb
(to produce DllModule.netmodule-file).
C++-code : TryVbDllLoad : Console application
TryVbDllLoad.cpp
#using <mscorlib.dll>
#using ".\..\ClassLibrary1\DllModule.netmodule"
using namespace DllModule::DllModuleNS;
int _tmain(int argc, _TCHAR* argv[])
{
Class1^ me = gcnew Class1();
int a = 1, b = 2;
int xx = me->ClassAdd(a, b);
return 0;
}
In the TryVBDllLoad-project properties I changed:
Common Properties -> Framework and References : added DllModule-project as reference
Configuration Properties -> C/C++ -> General : /clr flag set
Configuration Properties -> Linker -> Input : Add Module To Assembly set to path to DllModule.netmodule (/ASSEMBLYMODULE:"DllModule.netmodule")
This resulted in that I could use the VB-class Class1 in VC++ code!
PROBLEM SOLVED!
I now took it one step further, and changed the TryVBDllLoad-project to a dll:
Configuration Properties -> General : Configurationtype Dynamic Library (.dll)
Configuration Properties -> Linker -> System : SubSystem Windows (/SUBSYSTEM:WINDOWS)
TryVbDllLoadClass.h
#ifndef TryVbDllLoadClass_H
#define TryVbDllLoadClass_H
class TryVbDllLoadClass
{
public:
TryVbDllLoadClass();
int Add(int a, int b);
};
#endif // TryVbDllLoadClass_H
TryVbDllLoadClass.cpp
#include "TryVbDllLoadClass.h"
#using <mscorlib.dll>
#using ".\..\ClassLibrary1\DllModule.netmodule"
using namespace DllModule::DllModuleNS;
TryVbDllLoadClass::TryVbDllLoadClass() {}
int TryVbDllLoadClass::Add(int a, int b)
{
Class1^ me = gcnew Class1();
int xx = me->ClassAdd(a, b);
return xx;
}
DllExport.h
#ifndef DLLEXPORT_H
#define DLLEXPORT_H
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#ifdef __dll__
#define IMPEXP __declspec(dllexport)
#else
#define IMPEXP __declspec(dllimport)
#endif // __dll__
extern "C" {
IMPEXP int __stdcall AddFunction(int);
}
#endif // DLLEXPORT_H
DllMain.h
#define __dll__
#include "dllExport.h"
#include " TryVbDllLoadClass.h"
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
TryVbDllLoadClass * my;
IMPEXP int __stdcall AddFunction(int first, int second)
{
my = new TryVbDllLoadClass();
int res = my->Add(first, second);
delete my;
return res;
}
This dll I could then add to a non-visual-studio project just like a normal dll:
C++-code : LoadDll : Non-Visual-Studio-project (CodeBlocks in this case)
main.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "dllExport.h"
typedef int( * LPFNDLL_CREATE)(int, int);
HINSTANCE hDLL;
LPFNDLL_CREATE func;
using namespace std;
int main()
{
cout << "Hello world!" << endl;
int key = 35;
hDLL = LoadLibrary("TryVbDllLoadClass.dll");
if(hDLL)
{
cout << "Loaded: " << hDLL << endl;
func = (LPFNDLL_CREATE) (GetProcAddress(hDLL, "_AddFunction#4"));
if(func != NULL)
{
cout << "Connected: " << func << endl;
cout << "Function returns: " << func(key, key) << endl;
}
else cout << " ::: fail: " << GetLastError() << endl;
FreeLibrary(hDLL);
cout << "Freed" << endl;
}
else cout << " ::: fail: " << GetLastError() << endl;
printf("-> Goodbye world!\n");
return 0;
}
This way I can use the VB-classes given to me in my existing C++-project created outside Visuabl Studio. Finally...:)
With VB you do not get a "normal" DLL (at least this was the case in former times).
And you do not get Entry Points for functions.
But as i understood you, you have the VB source code and you can do with it whatever
is necessary. Here is a possible solution:
http://www.codeproject.com/Articles/21/Beginner-s-Tutorial-Calling-Visual-Basic-ActiveX-D
but try out first this less complicated way,
because i think a VB dll is always a COM dll, so you can:
register the dll using the Windows command
regsvr32 F:\proj\VBDllModule.dll
now your C++ code :
#import "F:\proj\VBDllModule.dll"
using namespace DllModule;
void CDialogTestDlg::OnButton1()
{
HRESULT hresult;
CLSID clsid;
_CTest *t; // a pointer to the CTest object
_bstr_t bstrA = L"hello";
_bstr_t bstrB = L" world";
_bstr_t bstrR;
::CoInitialize(NULL);
hresult=CLSIDFromProgID(OLESTR("VBTestLib.CTest"), &clsid);
hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(_CTest),(LPVOID*) &t);
if(hresult == S_OK)
{
bstrR = t->vbConcat(bstrA , bstrB);
AfxMessageBox((char*)bstrR);
}
}