When I analysis a cpp file using clang、clangAST,etc,what ever the function parameter type is,the result is int * type - clang

When I analysis a cpp file using clang、clangAST,etc,what ever the function parameter type is,the result is int * type
how to get the real original type of function's parameter type in cpp file

Related

FindWindowA function does not yield the expected output in dart foreign function interface

The following dart code's expected output is the handle to the file explorer window but the output always comes out to be 0 even though the file explorer window does exist!
import 'package:ffi/ffi.dart';
import 'dart:ffi';
void main() {
DynamicLibrary dl = DynamicLibrary.open('user32.dll');
final func = dl.lookupFunction<
IntPtr Function(Pointer<Utf16>?, Pointer<Utf16>?),
int Function(Pointer<Utf16>?, Pointer<Utf16>?)
>('FindWindowA');
print(func(nullptr, 'File Explorer'.toNativeUtf16()));
}
I have ran the function FindWindowA in a c++ program and it has returned the exptected output with the same input values that are NULL and 'File Explorer'.
In dart using null throws the error Invalid argument(s): argument value for ':ffi_param1' is null; hence the use of nullptr
FindWindowA does not take pointers to UTF-16 strings. The A in FindWindowA stands for "ANSI", which is Microsoft's way of indicating that it uses strings with single-byte code units encoded in the system's local encoding. (This is also indicated by its signature, which takes LPCSTR arguments.)
If you want to pass UTF-16 strings (which in Microsoft Windows are considered "wide strings"), then use FindWindowW.

Dart: A value of type 'int' can't be assigned to a variable of type 'int' [duplicate]

This question already has answers here:
The argument type 'String' can't be assigned to the parameter type 'String'
(3 answers)
Closed 1 year ago.
When I write an extension like so:
extension MyExtension<int> on List<int> {
void myMethod() {
int a = 1; // error
}
}
I get a seemingly nonsensical error message from the compiler:
A value of type 'int' can't be assigned to a variable of type 'int'.
Try changing the type of the variable, or casting the right-hand type to 'int'. dart(invalid_assignment)
I can fix the problem by removing <int> after the extension name:
extension MyExtension on List<int> {
void myMethod() {
int a = 1;
}
}
But I'd like to know what was going on in the original problematic code. What was the reason for the cryptic error message?
So you are having a simple problem, you are reassigning the meaning of int
extension MyExtension<int> on List<int>
Your extension takes a type argument, which means that when using the extension, you can pass many different types to it, but the name of this new type argument is int.
So you are assigning an int (the number) to int (the type argument) which is impossible because dart does not know if int (the type argument) will be an int.
In order to fix this, you can remove the type argument as you did, the code you show does not need a type argument, you can also rename the type argument, the convention says type arguments should be called T:
extension MyExtension<T> on List<int> ...
if what you want is for the type argument to always be an int, or a class that extends int you can also declare that:
extension MyExtension<T extends int> on List<int> ...
If you still have trouble understanding what type arguments are and how they work, here is the documentation for type arguments and here is the documentation for extensions with type arguments

How to stop clang AST misinterpreting this type of function declaration as a variable declaration?

I am using clang's abstract syntax tree generation to generate an AST for some source files. It maps out normal functions great, however it trips up on some functions, mislabeling them as variable declarations. When it does this it waits for a semicolon to finish this declaration and so does not map out the rest of the source file following the problem function. Is there a way to make clang realize that it's a function definition, not a variable declaration?
I put a semicolon after the function definition and doing that makes clang ignore the contents of the function, but at least it generates nodes for the code following it in the source file. I'm using the prophy python interface to interact with clang in my scripts, but ran clang manually and found the same thing.
This is an example of a function that clang does map:
int killProcess(int pid)
{
int ret=1;
HANDLE pHandle;
if ((pHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid)) != NULL)
if(!TerminateProcess(pHandle,0)) {
ret=0;
CloseHandle(pHandle);
}
return ret;
}
This is an example of a function which clang thinks is a variable declaration and ignores everything after it if there is no semicolon after the closing brace:
DWORD WINAPI listProcessesThread(LPVOID param)
{
char sendbuf[IRCLINE];
LPROC lproc = *((LPROC *)param);
LPROC *lprocp = (LPROC *)param;
lprocp->gotinfo = TRUE;
sprintf(sendbuf,"[PROC]: Listing processes:");
if (!lproc.silent) irc_privmsg(lproc.sock,lproc.chan,sendbuf,lproc.notice);
if (listProcesses(lproc.sock,lproc.chan,lproc.notice,NULL, FALSE, lproc.full) == 0)
sprintf(sendbuf,"[PROC]: Process list completed.");
else
sprintf(sendbuf,"[PROC]: Process list failed.");
if (!lproc.silent) irc_privmsg(lproc.sock, lproc.chan, sendbuf, lproc.notice);
addlog(sendbuf);
clearthread(lproc.threadnum);
ExitThread(0);
}
The expected results would be that clang knows that this is a function and generates a corresponding AST, however it doesn't. It constructs a VAR_DECL node with the spelling "WINAPI" instead of a "FUNCTION_DECL" node. The error it gives upon running "clang -cc1 -ast-dump processes2.cpp" is:
`-VarDecl 0x5625ad7ab2e0 col:7 invalid WINAPI 'int'
1 error generated.
At the end of its log. The abstract syntax tree up until this point is generated and displayed.
NB: I do not have WINAPI library installed because I am working on a Ubuntu machine.

How can I use a command line argument as the argument for a type provider?

What's the proper way to use a dynamic value as the argument for a type provider like CsvProvider? I'd expect this to work:
open System.IO
open FSharp.Data
[<EntryPoint>]
let main argv =
type Stock = CsvProvider<argv.[0]>
let stockData = Stock.Load(argv.[0])
for row in stockData.Rows do
printfn "(%A, %A, %A, %A)" row.High row.Low row.Open row.Close
0 //Exit
What am I doing wrong?
You can't use a command-line argument as the static argument for the type provider. The line type Stock = CsvProvider<argv.[0]> requires the parameter to CsvProvider to be a compile-time constant, because the types generated by the type provider are created a compile-time, not at run-time.
You can supply a different value to the Load function, and this can be a run-time value, as in your line Stock.Load(argv.[0]), but you will need to use a compile-time constant file name or sample data that matches the expected layout of the file being passed as a command-line argument, so that the types generated at compile-time will match the structure of the file being passed in at run-time (even though the data may be different).
For any type provider you're going to need a schema so that the compiler can understand what the shape of your data looks like. Consequently it has to be something that's available at compile time. One way to do this is to put it in a file:
High,Low,Open,Close
29.53,29.17,29.45,29.23
29.70,29.40,29.61,29.50
29.65,29.07,29.07,29.56
29.57,29.18,29.47,29.34
Which you can then import outside of your main function like so:
// or whatever you called the file
type Stock = CsvProvider<"schema.csv">
CsvProvider also lets you just give it a schema inline if you prefer:
type Stock = CsvProvider<"High,Low,Open,Close
29.53,29.17,29.45,29.23">
Here it is in the context of the whole program:
open System.IO
open FSharp.Data
type Stock = CsvProvider<"schema.csv">
[<EntryPoint>]
let main argv =
let stockData = Stock.Load(argv.[0])
for row in stockData.Rows do
printfn "(%A, %A, %A, %A)" row.High row.Low row.Open row.Close
0

Converting C headers to Delphi - Opaque Data Type

During the conversion process I come across the following C code:
/** Opaque data type for the error object.
*/
typedef struct kError * KErrorRef;
Where is kError declared?
The conversion tool provided by Rudy Velthuis produces this code:
type
{$EXTERNALSYM KErrorRef}
KErrorRef = ^kError;
When I try to compile it, I get this error message:
[dcc32 Error] ukError.pas(50): E2003 Undeclared identifier: 'kError'
What is the appropriate way of converting the C code?
Where is kError declared?
Nowhere, because it is not actually needed.
In this declaration:
typedef struct kError * KErrorRef;
struct kError is an incomplete type, which is allowed when used with a pointer.
The declaration is roughly equivalent to this:
// forward declaration of some as-yet unknown struct type
struct kError;
// this is OK; compiler knows the size of a pointer, which is not
// affected by the size of the actual struct being pointed to
typedef kError *KErrorRef;
The conversion tool provided by Rudy Velthuis produces this code
The tool is not producing the correct Delphi code in this instance. When dealing with a typedef for an incomplete (forward-declared) struct type, it should produce Delphi code more like this instead, if the actual struct type is not declared later on:
type
{$EXTERNALSYM KErrorRef}
KErrorRef = ^kError;
{$NODEFINE kError}
kError = record
end;
I'd declare an empty record and then a pointer to it. That gives you type safety.
type
KErrorRef = ^kError;
kError = record
end;

Resources