Externs and DLL imports - dllimport

I have this rather strange looking couple of lines in my code, that I am trying to decipher. Does anyone know what it says?
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

That line is known as Platform Invoke, basically it's just making the function GetPrivateProfileString from kernel32.dll available to your program. Check out http://www.pinvoke.net/default.aspx/kernel32.GetPrivateProfileString for a little more information on that specific function.

Related

Basic understanding of calling kernel functions in NSIS

In NSIS, I was going through some API which calls some functions of Windows.
For example:
Kernel32::SetEnvironmentVariable(t, t)i ("VAR1", "$R0").r0
Kernel32::GetLocaleInfo(i,i,t,i)i(2048,0x2,.r0,${NSIS_MAX_STRLEN})i
As I am a newbie, can anyone please explain what is happening here ? What is t , i , .ro etc. ?
I know that kernel32 is a DLL and SetEnvironmentVariable & GetLocaleInfo are the functions defined in this DLL.
The documentation will tell you what t and i are.
The basic syntax for System::Call is module::function(parameters)return. Parameters and return are optional and they both follow the same basic format: type input output. Type is not optional if you need input and/or output.
Parameters and return can be repeated multiple times, this is only useful when the function prototype exists as a define but you sometimes see this syntax on the NSIS Wiki as well. Kernel32::SetEnvironmentVariable(t, t)i ("VAR1", "$R0").r0 is exactly the same as Kernel32::SetEnvironmentVariable(t "VAR1", t "$R0")i.r0. When using a define it would look like this:
!define SetEnvironmentVariable "Kernel32::SetEnvironmentVariable(t, t)i"
System::Call '${SetEnvironmentVariable}("VAR1", "$R0").r0'
It is helpful if you know a language like C/C++ or Delphi when using the System plug-in because you need to understand the basic Windows types and how functions are typically used.
If for example you wanted to call the GetWindowsDirectory function you would first look at the function on MSDN:
UINT WINAPI GetWindowsDirectory(_Out_ LPTSTR lpBuffer, _In_ UINT uSize);
Translating this to NSIS gives you a initial skeleton of Kernel32::GetWindowsDirectory(t, i)i (WINAPI is the default calling convention). t maps to the Windows TCHAR* type and i is a 32-bit integer, the same as ULONG, LONG, DWORD, INT, UINT, INT32 and UINT32 in the Windows SDK.
The only missing piece is the input and output. The MSDN declaration is decorated with SAL annotations so it is easy to see which parameters are input and which are output.
A working example might look something like this:
System::Call 'Kernel32::GetWindowsDirectory(t .r1, i ${NSIS_MAX_STRLEN})i .r0'
DetailPrint "Return=$0 Output1=$1"
. can be used as a "nothing" placeholder when there is no input. In this case we use it twice. The return value never has input when using System::Call and we also have one output-only parameter.
r1 and r0 are aliases for the $1 and $0 NSIS registers and these aliases must be used when you need the output of something. The plain NSIS register can be used as input but then the variable expansion happens inside NSIS and not in the plug-in and this can cause issues with quotes in strings and is not really recommended if the string might contain quotes or legal System plug-in syntax. I would therefore recommend that your first example is rewritten as Kernel32::SetEnvironmentVariable(t "VAR1", t R0)i.r0.
In C your second example would look something like
char mybuf[1024];
GetLocaleInfo(MAKELCID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT), LOCALE_SLANGUAGE, mybuf, sizeof(mybuf));

Groovy GStrings and numberformat

I'm writing a script in groovy to process some files and I have the following method to create the resulting filename
static String formatFileName(String prefix, int counter, String extension) {
String counterS = String.format('%04d', counter)
return "$prefix-$counterS$extension"
}
Is there a more elegant way of formatting the counter in a GString?
Frankly, there's not much you can do here. Making this any shorter is basically nitpicking.
As mentioned in tim_yates' comment, you could make this a one-liner
return "$prefix-${String.format('%04d', counter)}$extension"
I can think of only one way to make it even shorter, which is to give up on GStrings and use sprintf instead, which is another example of Groovy goodness. Namely, an extension method of the Object class. Personally, I find this easier to read than the braces mashup.
return sprintf("%s-%04d%s", prefix, counter, extension)

How to use strstrip for parsing a string in two parts

I would like to know hot to parse a string like this "hello world" into "helloworld" using the strstrip kernel function. I am developing a Linux Kernel char device and this functions causes me a Kernel Panic (or Kernel Opss).
The way I'm using this function is the following:
char result[100];
strcpy(result, "hello world");
strstrip(result);
strstrip(&result); //Also tried this
strstrip("100+200"); //Also tried this
The Kernel error is caused as soon as the strstrip line gets executed. What is the proper way to call this function?
Actually strstrip helps to remove the white spaces at the front. It does not remove all the white spaces with in the string.
Please look at the below example.
char result[100];
strcpy(result, " hello world from stack exchange");
printk("\n before: %s",result);
strcpy(result, strstrip((char*)result));
printk("\n after: %s",result);
Hope it helps.
srtstrip() is a wrapper function for strim() (http://lxr.linux.no/linux+v3.11.2/lib/string.c#L361) in modern kernels. As it will attempt to modify the string itself, you cannot call it with a static string as you have in the third attempt.
The second attempt you have is passing a pointer to an array variable which is also a pointer. So you are passing a char** which if you look at the link above you can see is not correct.
The first attempt should not cause a kernel error, but you do not appear to be receiving the return value in a a local variable. What kind of error are you receiving? I will update this answer if you can provide that information.
In the end though as Balamurugan A points out, this function does not do what you seem to think it does. strsep() (http://lxr.linux.no/linux+v3.11.2/lib/string.c#L485) may help you out here but it will only be a stepping stone to removing all spaces. You will actually have to copy the string into a new buffer word by word as there is not way to simply "shift memory contents", as it were.

Using the C preprocessor to determine current scope?

I am developing an application in C / Objective-C (No C++ please, I already have a solution there), and I came across an interesting use case.
Because clang does not support nested functions, my original approach will not work:
#define CREATE_STATIC_VAR(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
This code would compile fine with GCC, but because clang doesn't support nested functions, I get a compile error:
Expected ';' at end of declaration.
So, I found a solution that works for Clang on variables inside a function:
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
However, I was wondering if there was a way to leverage macro concatenation to choose the appropriate one for the situation, something like:
#define CREATE_STATIC_VAR_GLOBAL(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
#define SCOPE_CHOOSER LOCAL || GLOBAL
#define CREATE_STATIC_VAR(Type, Name, DFLT) CREATE_STATIC_VAR_ ## SCOPE_CHOOSER(Type, Name, Dflt)
Obviously, the ending implementation doesn't have to be exactly that, but something similar will suffice.
I have attempted to use __builtin_constant_p with __func__, but because __func__ is not a compile-time constant, that wasn't working.
I have also tried to use __builtin_choose_expr, but that doesn't appear to work at the global scope.
Is there something else I am missing in the docs? Seems like this should be something fairly easy to do, and yet, I cannot seem to figure it out.
Note: I am aware that I could simply type CREATE_STATIC_VAR_GLOBAL or CREATE_STATIC_VAR_LOCAL instead of messing with macro concatenation, but this is me attempting to push the limits of the compiler. I am also aware that I could use C++ and get this over with right away, but that's not my goal here.
#define SCOPE_CHOOSER LOCAL || GLOBAL
#define CREATE_STATIC_VAR(Type, Name, DFLT) CREATE_STATIC_VAR_ ## SCOPE_CHOOSER(Type, Name, Dflt)
The biggest difficulty here is that the C preprocessor works by textual substitution, so even if you figured out how to get SCOPE_CHOOSER to do what you want, you'd end up with a macro expansion that looked something like
CREATE_STATIC_VAR_LOCAL || GLOBAL(Type, Name, Dflt);
There's no way to get the preprocessor to "constant-fold" macro expansions during substitution; the only time things are "folded" is when they appear in #if expressions. So your only hope (modulo slight handwaving) is to find a single construction that will work both inside and outside of a function.
Can you explain more about the ultimate goal here? I don't think you can load the variable's initial value with __attribute__((constructor)), but maybe there's a way to load the initial value the first time the function body is entered... or register all the addresses of these variables into a global list at compile-time and have a single __attribute__((constructor)) function that traverses that list... or some mishmash of those approaches. I don't have any specific ideas in mind, but maybe if you give more information something will emerge.
EDIT: I don't think this helps you either, since it's not a preprocessor trick, but here is a constant-expression that will evaluate to 0 at function scope and 1 at global scope.
#define AT_GLOBAL_SCOPE __builtin_types_compatible_p(const char (*)[1], __typeof__(&__func__))
However, notice that I said "evaluate" and not "expand". These constructs are compile-time, not preprocessing-time.
Inspired by the #Qxuuplusone answer.
The suggested macro for AT_GLOBAL_SCOPE does indeed work (in GCC), but causes a compiler warning (and I am pretty sure it cannot be silenced by Diagnostic Pragma because it's created by pedwarn with a test here).
Unless you turn on -w you will always see these warnings and have, in the back of your mind, a horrible feeling that you probably shouldn't be doing whatever it is that you are doing.
Fortunately, there is a solution that can silence these lingering doubts.
In the Other Builtins section, there is __builtin_FUNCTION with this very interesting description (emphasis mine):
This function is the equivalent of the __FUNCTION__ symbol and returns an address constant pointing to the name of the function from which the built-in was invoked, or the empty string if the invocation is not at function scope.
It turns out, at least in version 8.3 of GCC, you can do this:
#define AT_GLOBAL_SCOPE (__builtin_FUNCTION()[0] == '\0')
This still probably won't answer the original question, but until GCC decides this too will cause a warning (it kind of seems like it's intentionally designed not to though), it lets me continue doing questionable things using macros without anything to warn me that it's a bad idea.

How do I PInvoke a multi-byte ANSI string?

I'm working on a PInvoke wrapper for a library that does not support Unicode strings, but does support multi-byte ANSI strings. While investigating FxCop reports on the library, I noticed that the string marshaling being used had some interesting side effects. The PInvoke method was using "best fit" mapping to create a single-byte ANSI string. For illustration, this is what one method looked like:
[DllImport("thedll.dll", CharSet=CharSet.Ansi)]
public static extern int CreateNewResource(string resourceName);
The result of calling this function with a string that contains non-ASCII characters is that Windows finds a "close" character, generally this looks like it ends up being "???". If we pretend that 'a' is a non-ASCII character, then passing "cat" as a parameter would create a resource named "c?t".
If I follow the guidelines in the FxCop rule, I end up with something like this:
[DllImport("thedll.dll", CharSet=CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern int CreateNewResource([MarshalAs(UnmanagedType.LPStr)] string resourceName);
This introduces a change in behavior; now when a character cannot be mapped an exception is thrown. This concerns me because this is a breaking change, so I'd like to try and marshal the strings as multi-byte ANSI but I cannot see a way to do so. UnmanagedType.LPStr is specified to be a single-byte ANSI string, LPTStr will be Unicode or ANSI depending on the system, and LPWStr is not what the library expects.
How would I tell PInvoke to marshal the string as a multibyte string? I see there's a WideCharToMultiByte() API function, could I change the signature to expect an IntPtr to a string I create in unmanaged memory? It seems like this still has many of the problems that the current implementation has (it still might have to drop or substitute characters), so I'm not sure if this is an improvement. Is there another method of marshaling that I'm missing?
ANSI is multi-byte, and ANSI strings are encoded according to the codepage currently enabled on the system. WideCharToMultiByte works the same way as P/Invoke.
Maybe what you're after is conversion to UTF-8. Although WideCharToMultiByte supports this, I don't think P/Invoke does, since it's not possible to adopt UTF-8 as the system-wide ANSI code page. At this point you'd be looking at passing the string as an IntPtr instead, although if you're doing that, you may as well use the managed Encoding class to do the conversion, rather than WideCharToMultiByte.
Here is the best way I've found to accomplish this. Instead of marshalling as a string, marshal as a byte[]. Put the responsibility on the caller of the pinvoke function API to convert to a byte array in the most appropriate fashion. Most likely by using one of the Text.Encoding classes.
If you end up having to call WideCharToMultiByte manually, I would get rid of the p/invoke and manually marshal this using WideCharToMultiByte in a C++/CLI wrapper function. Managed C++ is much better at these interop scenarios than C# is.
Though, if this is the only p/invoke you have, it's probably not worth it.

Resources