Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Calling C++ dll in C#: DWORD_PTR, DWORD, TCHAR* ?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Dr.Disrespect
Master Cheater
Reputation: 1

Joined: 17 Feb 2016
Posts: 490

PostPosted: Sun Apr 23, 2017 12:00 pm    Post subject: Calling C++ dll in C#: DWORD_PTR, DWORD, TCHAR* ? Reply with quote

I have a function in C++, which returns a data of DWORD_PTR type. It also has DWORD and TCHAR* as its parameter types.

However, when I import this C++ dill into my C# project, the three types above could not be compiled.

I did some research and changed "DWORD_PTR" to "int", "DWORD" to "uint". But I couldn't figure out what TCHAR* is in C#.

Thanks in advance.

Edit:
To make things clearer:

In C++ dll:
Code:

DWORD_PTR test(DWORD ProcID, TCHAR* name)



In C#:
Code:

[DllImport("cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int test(uint ProcID, TCHAR* name); <----this is wrong, how to fix it based on the c++ function?

_________________
**************

A simple example is better then ten links. Very Happy
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 137

Joined: 25 Jan 2006
Posts: 7306
Location: 127.0.0.1

PostPosted: Sun Apr 23, 2017 5:00 pm    Post subject: This post has 1 review(s) Reply with quote

DWORD_PTR depends on if you are compiling for 32bit or 64bit.

32bit, DWORD_PTR is actually 'unsigned long'.
64bit, DWORD_PTR is actually 'unsigned __int64'.

Generally, either way you would use IntPtr and compile the C# application according to how the DLL is compiled. IntPtr is 4 bytes in 32bit, and 8 bytes in 64bit.

DWORD would be uint.

TCHAR* depends on how the DLL is compiled as well. You should honestly not use TCHAR unless the code is subject to being released in either unicode or ansi at the same time. If you are coding for specific use, there is no reason to use it and instead, you should use either char* or wchar_t* directly.

Which ever you decide, C# allows you to pass character pointers in multiple ways back and forth between the native and managed sides. The most common is using a StringBuilder object as the parameter. You can also use byte[], char[] and enforcing the type via 'UnmanagedType' attributes. But StringBuilder is the more common method used. Be sure that you set the proper 'CharSet' in the DllImport attributes list as well.

Such as the following:
Code:

[DllImport("cpp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr test(uint ProcID, StringBuilder name);

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Dr.Disrespect
Master Cheater
Reputation: 1

Joined: 17 Feb 2016
Posts: 490

PostPosted: Sun Apr 23, 2017 5:46 pm    Post subject: Reply with quote

atom0s wrote:
DWORD_PTR depends on if you are compiling for 32bit or 64bit.

32bit, DWORD_PTR is actually 'unsigned long'.
64bit, DWORD_PTR is actually 'unsigned __int64'.

Generally, either way you would use IntPtr and compile the C# application according to how the DLL is compiled. IntPtr is 4 bytes in 32bit, and 8 bytes in 64bit.

DWORD would be uint.

TCHAR* depends on how the DLL is compiled as well. You should honestly not use TCHAR unless the code is subject to being released in either unicode or ansi at the same time. If you are coding for specific use, there is no reason to use it and instead, you should use either char* or wchar_t* directly.

Which ever you decide, C# allows you to pass character pointers in multiple ways back and forth between the native and managed sides. The most common is using a StringBuilder object as the parameter. You can also use byte[], char[] and enforcing the type via 'UnmanagedType' attributes. But StringBuilder is the more common method used. Be sure that you set the proper 'CharSet' in the DllImport attributes list as well.

Such as the following:
Code:

[DllImport("cpp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr test(uint ProcID, StringBuilder name);


Thanks a lot, atom0s!

I have two follow up questions tho: Very Happy

1. I would probably use unicode as my character set in accordance with my C++ dll. Does that affect the second parameter in the function? I see you used ANSI in your code, not unicode.

2. I will change "TCHAR*" to "wchart_t". But what's the different between TCHAR, char, WCHAR, wchar_t?.... It's confusing....

_________________
**************

A simple example is better then ten links. Very Happy
Back to top
View user's profile Send private message
Deine Mutter
Expert Cheater
Reputation: 1

Joined: 05 Apr 2006
Posts: 181

PostPosted: Mon Apr 24, 2017 2:56 am    Post subject: This post has 1 review(s) Reply with quote

fmanager wrote:
But what's the different between TCHAR, char, WCHAR, wchar_t?.... It's confusing....


TCHAR is a macro which resolves to wchar_t if you compile with Unicode, otherwise it resolves to char.

An example which demonstrates this:
Code:
$ type test.c
#include <stdio.h>
#include <windows.h>

void main()
{
    printf("%zu\n", sizeof(TCHAR));
}

$ cl test.c /Fe:no_unicode.exe
[...]

$ cl test.c /DUNICODE /D_UNICODE /Fe:unicode.exe
[...]

$ no_unicode.exe
1

$ unicode.exe
2


The idea is that TCHAR makes your code independent of the charset that it is compiled with. So adding/removing Unicode support is just a matter of modifying compilation flags instead of changing the code.

_________________
Back to top
View user's profile Send private message
Dr.Disrespect
Master Cheater
Reputation: 1

Joined: 17 Feb 2016
Posts: 490

PostPosted: Tue Apr 25, 2017 10:43 am    Post subject: Reply with quote

Deine Mutter wrote:
fmanager wrote:
But what's the different between TCHAR, char, WCHAR, wchar_t?.... It's confusing....


TCHAR is a macro which resolves to wchar_t if you compile with Unicode, otherwise it resolves to char.

An example which demonstrates this:
Code:
$ type test.c
#include <stdio.h>
#include <windows.h>

void main()
{
    printf("%zu\n", sizeof(TCHAR));
}

$ cl test.c /Fe:no_unicode.exe
[...]

$ cl test.c /DUNICODE /D_UNICODE /Fe:unicode.exe
[...]

$ no_unicode.exe
1

$ unicode.exe
2


The idea is that TCHAR makes your code independent of the charset that it is compiled with. So adding/removing Unicode support is just a matter of modifying compilation flags instead of changing the code.


Thank you, Deine Mutter. +Rep

_________________
**************

A simple example is better then ten links. Very Happy
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 137

Joined: 25 Jan 2006
Posts: 7306
Location: 127.0.0.1

PostPosted: Tue Apr 25, 2017 5:25 pm    Post subject: Reply with quote

fmanager wrote:
Thanks a lot, atom0s!

I have two follow up questions tho: Very Happy

1. I would probably use unicode as my character set in accordance with my C++ dll. Does that affect the second parameter in the function? I see you used ANSI in your code, not unicode.

2. I will change "TCHAR*" to "wchart_t". But what's the different between TCHAR, char, WCHAR, wchar_t?.... It's confusing....


1. Yes, you will need to change the CharSet to be unicode instead if you plan for the C++ DLL to be using Unicode for its function.

2. As Deine Mutter pointed out, TCHAR is just a macro definition that changes based on the configuration settings of your project. If you are compiling with the character set as Unicode, TCHAR will point to wchar_t, and if you are set to multibyte, it will point to char.

Generally, things like TCHAR only matter if you are making projects that need to be compiled and released in both unicode and ansi charsets. If you are doing basic things like a trainer, or a simple app of your own that does not need the dual releases, there is really no need to use TCHAR or its TCHAR based API calls.

For example, in multibyte there is:
strcpy, strcpy_s and so on.

In unicode, it would be:
wcscpy, wcscpy_s and so on.

If you are using TCHAR, you would be using the macros:
_tcscpy, _tcscpy_s and so on.

In multibyte, _tcscpy_s would point to strcpy_s, in unicode it would point to wcscpy_s.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Deine Mutter
Expert Cheater
Reputation: 1

Joined: 05 Apr 2006
Posts: 181

PostPosted: Wed Apr 26, 2017 10:06 am    Post subject: Reply with quote

Maybe I should have pointed out that I also wouldn't recommend the usage of tchar nowadays. The purpose of tchar was to fix legacy and compatibility issues which don't exist on modern systems anymore. Even Microsoft goes as far as saying:
https://msdn.microsoft.com/en-us/library/ff381407(VS.85).aspx wrote:
The TEXT and TCHAR macros are less useful today, because all applications should use Unicode. However, you might see them in older code and in some of the MSDN code examples.

Nowadays, tchar and all the wrappers (_T, TEXT, _tprintf, etc..) that come with it are just a really easy and fast way to clutter your code and make it less readable. As Wiccan pointed out: just assume a charset (preferrably Unicode, especially when you ship the application) and move on.

_________________
Back to top
View user's profile Send private message
Dr.Disrespect
Master Cheater
Reputation: 1

Joined: 17 Feb 2016
Posts: 490

PostPosted: Wed Apr 26, 2017 5:53 pm    Post subject: Reply with quote

atom0s wrote:
fmanager wrote:
Thanks a lot, atom0s!

I have two follow up questions tho: Very Happy

1. I would probably use unicode as my character set in accordance with my C++ dll. Does that affect the second parameter in the function? I see you used ANSI in your code, not unicode.

2. I will change "TCHAR*" to "wchart_t". But what's the different between TCHAR, char, WCHAR, wchar_t?.... It's confusing....


1. Yes, you will need to change the CharSet to be unicode instead if you plan for the C++ DLL to be using Unicode for its function.

2. As Deine Mutter pointed out, TCHAR is just a macro definition that changes based on the configuration settings of your project. If you are compiling with the character set as Unicode, TCHAR will point to wchar_t, and if you are set to multibyte, it will point to char.

Generally, things like TCHAR only matter if you are making projects that need to be compiled and released in both unicode and ansi charsets. If you are doing basic things like a trainer, or a simple app of your own that does not need the dual releases, there is really no need to use TCHAR or its TCHAR based API calls.

For example, in multibyte there is:
strcpy, strcpy_s and so on.

In unicode, it would be:
wcscpy, wcscpy_s and so on.

If you are using TCHAR, you would be using the macros:
_tcscpy, _tcscpy_s and so on.

In multibyte, _tcscpy_s would point to strcpy_s, in unicode it would point to wcscpy_s.


@atom0s Thank you for the detailed example. I will +rep when I am allowed to. Smile

@Deine Mutter, thanks for the reminder. Smile

_________________
**************

A simple example is better then ten links. Very Happy
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites