Used to. NET programming, especially those that have never used basic, Pascal, C/C ++, and other "older" Languages Program Personnel, in case of pinvoke, especially com interoperation, are often confused. I believe that in the future, on the one hand, from C #,. net and Java start to learn programming more and more people, on the one hand, the whole windows is also gradually migrated to the managed platform, there will be fewer and fewer programmers who know how to deal with WIN32API directly (of course, there must be a lot of programmers, at least more than writing drivers with DDK ......)
However,. net programmers, although they do not need to directly use C ++ to call APIs, pinvoke's knowledge is still indispensable. For handle, unmanaged thread, COM, and other basic things, it is still a required course. Therefore, I want to use tips to sort out the most basic content I know.
After talking a lot of nonsense, let's take a look at the actual example of pinvoke:
In a Windows form written by C #, resource dll must be read (resource DLL, Win32 format only contains resource DLL ). The following API function is used:
Bool enumresourcetypes (
Hmodule,
Enumrestypeproc lpenumfunc,
Long_ptr lparam
);
Here, enumrestypeproc is defined:Bool callback enumrestypeproc (
Hmodule,
Lptstr lpsztype,
Long_ptr lparam
);
How should I write lptstr in C? I want to write down the following if I don't want.CodeThere won't be too few friends:
Public Delegate Bool Enumrestypeproc (intptr hmodule, String Strtype, intptr PARAM );
Unfortunately, this code will go wrong during execution-view it with Marshal. getlastwin32error () and find it is error_noaccess (998 ).
Note: The program accesses the address space that is not allowed to be accessed. After testing, the hmodule is the handle of the correct dll library, and the final parameter is also set to null, so the only reason is this strtype.
This parameter is of the lptstr type. In the Unicode environment, that is, lpwstr, that is, wchar * -- Yes, isn't it a string?
However, after carefully reading the msdn instructions, we will find that Windows provides some standard resource types, such as rt_icon, rt_string, rt_version ,...... Looking at the definitions of these types, you will find that they are all numbers.
That is to say, the lpsztype parameter can be used as a number or a pointer to an address in the memory. In this case, the. NET string type is obviously not supported. The correct method is to use intptr. If you judge that the value is not a system or defined type, convert the marshal value to a pointer to the string to obtain the string.
Conclusion: In. net, the data type is "strong type", you cannot use a cat as a horse, so it ensures the type security; however, in C/C ++ and other language-based Win32, the type can be changed at will. You can use a cat as a horse or even a pig ...... No one can guarantee the security of this change, but it also brings flexibility. In Windows, many data types have different names, but their actual data structures are the same (for example, there are many handle types such as hwnd, hmenu, hinstance, and hhook ). On the contrary, there are many examples of the same data type, which sometimes represent a value or a pointer.