I a porting a large amount of code from Visual Studio to mingw unicode enabled project and I ran into this issue.It seems that the parameters I am passing from the derived class to the base class do not match. Atleast thats my assumption. I am suspecting that the issue is with the type LPCSTR Looking into this type in mingw I get the follwoing typedef
typedef CONST CHAR *LPCSTR,*PCSTR;
Now this is the base class
#ifdef UNICODE
CBasePin(
__in_opt LPCSTR pObjectName,
__in CBaseFilter *pFilter,
__in CCritSec *pLock,
__inout HRESULT *phr,
__in_opt LPCWSTR pName,
PIN_DIRECTION dir);
#endif
This is the class that inherits from the base class and passes the parameters to the base class.
CAsyncOutputPin::CAsyncOutputPin(
HRESULT * phr,
CAsyncReader *pReader,
CAsyncIo *pIo,
CCritSec * pLock)
: CBasePin(
TEXT("Text Pin"),
pReader,
pLock,
phr,
TEXT("Output"),
PINDIR_OUTPUT
),
m_pReader(pReader),
m_pIo(pIo)
,m_bQueriedForAsyncReader(false) ////
{
}
This is the linker error I am getting at the constructor initialization list
undefined reference to `CBasePin::CBasePin(wchar_t const*, CBaseFilter*, CCritSec*, long*, wchar_t const*, _PinDirection)'|
any suggestions on why I am getting this linker error. I am a bit puzzled as to why this is a linker error. I was guessing if it was a type mismatch or something it would show up as a compiler error. Any suggestions on how I can resolve this issue for Mingw 64bit gcc ?
your CBasePin has a parameter LPCSTR pObjectName (which is of type const char*) and a parameter LPCWSTR pName (whichis of type const wchar_t*) and in your call to it you're using TEXT-macro on a char-literal ,so both those literals getting the L-prefix making them const wchar_t* when UNICODE is defined ,so there is a type mismatch on the pObjectName.
If UNICODE is not defined then you would get the same error but on pName.
Remove the first TEXT and it should be Ok (for UNICODE that is).
Why are you using the TEXT macro? You have one char * parameter and one wchar_t * parameter, and it can't do the right thing for both.
Just write what you mean. Something like
"Text Pin", ..., L"Output", ...
Related
Hi I'm trying to make mfc simple project to my final assignment in oop course, but after I install the mfc
I get error of:
1. STRCPY_S
The file that have the error is read only and I can't change it. I've tried to add CRT comment and change the precomplier but no result.
error description here
the line is gives the error:
inline void __cdecl strcpy_s(
_Out_writes_z_(_S1max) char *_S1,
_In_ size_t _S1max,
_In_z_ const char *_S2)
{
ATLMFC_CRT_ERRORCHECK(::strcpy_s(_S1, _S1max, _S2));
}
I am trying to get properties from an HWND. I'm used information from Using Window Properties, but the example below is not working for me. I'm getting an error while compiling my code.
argument of type "BOOL (__stdcall *)(HWND hwndSubclass, LPCSTR lpszString, HANDLE hData)" is incompatible with parameter of type "PROPENUMPROCEXW"
Here is my callback function
BOOL CALLBACK PropEnumProcEx(HWND hwndSubclass, LPCSTR lpszString, HANDLE hData) {
return TRUE;
}
and this how I'm using it
EnumPropsEx(hwnd, PropEnumProcEx, NULL);
Does someone have any suggestions of how this can be fixed?
LPCSTR lpszString should be LPTSTR lpszString. This argument should accept a pointer to either ANSI or Unicode null-terminated string. PROPENUMPROCEXW indicates that you are building Unicode application so EnumPropsEx macro expands to EnumPropsExW call so you need to provide callback accepting wide string as an argument. Typically you should always explicitly call Unicode variants of API functions.
Also you are missing last argument ULONG_PTR dwData.
So your callback should look like:
BOOL CALLBACK
PropEnumProcEx(HWND hwndSubclass, LPTSTR lpszString, HANDLE hData, ULONG_PTR dwData)
{
return TRUE;
}
This question already has answers here:
error: cannot convert 'const wchar_t [13]' to 'LPCSTR {aka const char*}' in assignment
(3 answers)
Closed 6 years ago.
Does anyone have any idea why this is happening?
#define _x64
#include <Windows.h>
#include <iostream>
#include <windef.h>
#include <Winuser.h>
#include <tchar.h>
using namespace std;
int WINAPI MessageBoxW(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
);
int main(){
std::cout << MessageBoxW(NULL, L"", L"", 0);
}
I am using compiling with Microsoft (R) Incremental Linker Version 14.00.24215.1 and using the "/EHsc" option at the command line for a command line input of "cl /EHsc winbasicb.cpp". I am not doing anything fancy I feel. Just using the /EHsc option for optimized compilation and linking.
I am getting this error.
/out:winbasicb.exe
winbasicb.obj
winbasicb.obj : error LNK2019: unresolved external symbol __imp_MessageBoxW referenced in function main
winbasicb.exe : fatal error LNK1120: 1 unresolved externals
I have read error: cannot convert 'const wchar_t [13]' to 'LPCSTR {aka const char*}' in assignment, but that was not helpful because they're getting a compiler error but I'm getting a linker error. In that question, the error was due to using MessageBoxW(..., "", "", ...) instead of MessageBoxW(..., L"", L"", ...), but I used L"" as I should but I'm getting a linker error.
In Windows there are two versions of just about all Windows API functions.
If you see the "Requirements" section of this reference page you will see that there is one MessageBoxW and one MessageBoxA function. The symbol MessageBox is a macro defined as one of the actual functions depending on the UNICODE macro.
The MessageBoxW function expects the strings to be wide-character strings, which is what you pass. Unfortunately it seem you don't have the correct Unicode settings, so the ANSI (narrow character, plain char) version MessageBoxA is used instead.
There are two solutions: Either make sure you have the correct Unicode settings. Or by explicitly call MessageBoxW. Or don't use wide-character strings (i.e. drop the L prefix).
You are calling the TCHAR version of MessageBox(). The conversion error message is complaining that you are passing Unicode strings to MessageBoxA(), which expects Ansi strings instead. This means your project is being compiled without UNICODE defined, thus TCHAR maps to char and MessageBox() maps to MessageBoxA(). But the L prefix is used to create Unicode literals, not Ansi literals.
When passing string literals to TCHAR based functions, use the TEXT() macro to ensure proper character encoding:
int msgboxID = MessageBox(
NULL,
TEXT("temp.txt already exists.\nDo you want to replace it?"),
TEXT("Confirm Save As"),
MB_ICONEXCLAMATION | MB_YESNO
);
Otherwise, stay away from the TCHAR functions (TCHAR should only be used when compiling the same codebase for both Win9x/ME and NT4+ Windows families), use the Ansi or Unicode functions directly instead:
int msgboxID = MessageBoxA(
NULL,
"temp.txt already exists.\nDo you want to replace it?",
"Confirm Save As",
MB_ICONEXCLAMATION | MB_YESNO
);
int msgboxID = MessageBoxW(
NULL,
L"temp.txt already exists.\nDo you want to replace it?",
L"Confirm Save As",
MB_ICONEXCLAMATION | MB_YESNO
);
I have an existing Win32 C++ DLL, which needs to be accessed by a VB6 client. One of the exported functions is defined as follows:
__declspec(dllexport) long __stdcall Foo(long nId, LPCWSTR pszwPath = nullptr);
Unfortunately, VB6 always converts strings to ANSI when calling DLL functions via a Declare statement. In order to bypass this limitation, I have embedded a type library, which features the following signature for the function:
[uuid(...)]
library FooLib
{
[
helpstring("FooLib"),
dllname("Foo.dll")
]
module FooMdl
{
[entry("Foo")]
long __stdcall Foo([in] long nId, [in,unique,string,defaultvalue(0)] LPCWSTR pszwPath);
}
};
This won't compile however, as MIDL generates the following error:
error MIDL2020 : error generating type library : AddFuncDesc failed : Foo
My next attempt involved utilizing the optional attribute:
long __stdcall Foo([in] long nId, [in,unique,string,optional] LPCWSTR pszwPath);
While this type library can be compiled successfully, the VB6 client crashes with an access violation as soon as the optional string value is omitted.
I am aware that I could change the LPCWSTR argument to a BSTR type, thereby remedying the problem. However, this would also require me to change the signature and implementation of the existing DLL.
Is it therefore possible to define a char / wchar_t pointer argument as optional or with a NULL default value? Or am I simply out of luck here?
This has probably been asked before but I can't seem to find the solution:
std::string GetPath()
{
char buffer[MAX_PATH];
::GetSystemDirectory(buffer,MAX_PATH);
strcat(buffer,"\\version.dll");
return std::string(buffer);
}
This returns an error stating:
argument of type "char *" is incompatible with parameter of type "LPWSTR"
So yeah. Anyone got an answer?
You need to use the ansi version:
std::string GetPath()
{
char buffer[MAX_PATH] = {};
::GetSystemDirectoryA(buffer,_countof(buffer)); // notice the A
strcat(buffer,"\\version.dll");
return std::string(buffer);
}
Or use unicode:
std::wstring GetPath()
{
wchar_t buffer[MAX_PATH] = {};
::GetSystemDirectoryW(buffer,_countof(buffer)); // notice the W, or drop the W to get it "by default"
wcscat(buffer,L"\\version.dll");
return std::wstring(buffer);
}
Rather than call the A/W versions explicitly you can drop the A/W and configure the whole project to use ansi/unicode instead. All this will do is change some #defines to replace foo with fooA/W.
Notice that you should use _countof() to avoid incorrect sizes depending on the buffers type too.
If you compile your code using MultiByte support it will compile correctly,but when you compile it using Unicode flag it will give an error because in Unicode support ::GetSystemDirectoryA becomes ::GetSystemDirectoryW use consider using TCHAR instead of char.TCHAR is defined such that it becomes char in Multibyte flag and wchar_t with Unicode flag
TCHAR buffer[MAX_PATH];
::GetSystemDirectory(buffer,MAX_PATH);
_tcscat(buffer,_T("\\version.dll"));
You can use typedef for string /wstring so your code becomes independent
#ifdef UNICODE
typedef wstring STRING;
#else
typedef string STRING;
#endif
STRING GetPath()
{
TCHAR buffer[MAX_PATH];
::GetSystemDirectory(buffer,MAX_PATH);
_tcscat(buffer,_T("\\version.dll"));
return STRING(buffer);
}