Assigning a function pointer with a forward-declared prototype in Nim - function-pointers

I want to assign a Window Procedure to a Window Class structure:
var wndClass : WNDCLASS;
wndClass.lpszClassName = CLASSNAME;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
I can't assign WndProc yet because it hasn't been declared. When I use a forward declaration (described here):
proc WndProc(hWnd: HWND; msg: WINUINT; wParam: WPARAM; lParam: LPARAM) : LRESULT
I get this error:
Error: type mismatch: got (None) but expected 'WNDPROC'
Is my forward declaration wrong, or do I have to write the function first in this case?
Edit:
For reference, the following code works in global scope:
proc Foo : int32;
var bar = Foo();
var baz = Foo;
echo bar;
echo baz();
proc Foo : int32 =
return 4;
The definitions for WNDCLASS and WNDPROC can be found here:
http://nim-lang.org/windows.html

The problem was that even though the type definition of WNDPROC includes the pragmas, you have to repeat them in forward declarations.
This code compiles:
import windows
proc WndProc(hWnd: HWND; msg: WINUINT; wParam: WPARAM; lParam: LPARAM) : LRESULT {.stdcall.}
var wndClass : WNDCLASS;
wndClass.lpfnWndProc = WndProc;
proc WndProc(hWnd: HWND; msg: WINUINT; wParam: WPARAM; lParam: LPARAM) : LRESULT = 0
Incidentally, if you try to recreate the problem by including the types in the file, it fails because of case-insensitivity.

Related

How do you call an uncurried function with unit in ReScript/ReasonML?

Say that I have an uncurried function like:
let echo(. a) = a;
I can call this funcition fine with most literals like:
echo(. 1)
echo(. "Hello")
but when I am trying to call it with void, I get an error:
echo(. ()) //This function has arity1 but was expected arity0
As a workaround, I can do this:
let myArg = ()
echo(. myArg)
Is there a way to avoid this?
I like this version as well:
echo(. ignore())
that way I don't need the dummy value workaround
Edit: This version is also now part of the docs: https://rescript-lang.org/docs/manual/latest/function#uncurried-function
It looks like you are trying to call an un curried function that takes one parameter with no arguments because that is what () means right. The only reason it works with
echo(. myArg) is in this case the compiler is declaring an un initialized variable called myArg and passing that to echo.
EDIT: you can look at what I mean at re-script playground here
let echo = (. a) => a;
let k =() => echo(. "String")
let myArg = ()
let s =() => echo (. myArg)
generates
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';
function echo(a) {
return a;
}
function k(param) {
return echo("String");
}
function s(param) {
return echo(undefined);
}
var myArg;
exports.echo = echo;
exports.k = k;
exports.myArg = myArg;
exports.s = s;
/* No side effect */
Apparently, this is a known issue in rescript. See: https://github.com/rescript-lang/rescript-compiler/issues/3429

What is the best way to clear an entire structure in Structured text

This is how I have it now
TYPE MyType: STRUCT
name: STRING[20];
input: INT;
output: INT;
END_STRUCT
END_TYPE
PROGRAM PLC_PRG:
VAR
struct: MyType;
struct_NULL: MyType;
error: BOOL;
END_VAR
IF error THEN
struct := struct_NULL;
END_IF
END_PROGRAM
Is there another way to null the structure, without declearing and using struct_NULL
Just use SysMemSet (Codesys library SysMem), MemSet (Codesys library MemoryUtils) or MEMSET (TwinCAT 3 library Tc2_System) function to set all data to 0.
SysMemSet(
pDest := ADR(TestStruct),
udiValue := 0,
udiCount := SIZEOF(TestStruct)
);
You can write a simple helper function for it :)
FUNCTION F_Clear : BOOL
VAR_INPUT
Target : ANY;
END_VAR
VAR
END_VAR
SysMemSet(
pDest := Target.pValue,
udiValue := 0,
udiCount := Target.diSize
);
Usage, works for all kinds of variables!
F_Clear(TestStruct);
Yes, this would work, but can you guarantee that no one will write in the code something like this:
struct_NULL.input := 7;
So I would prefer to write an short function which set back all value to default:
FUNCTION F_setToDefault_MyStruct : MyStruct
VAR
DefaultStruct : MyStruct;
END_VAR
F_setToDefault_MyStruct := DefaultStruct;
So in the programm you can call:
//set struct to default values
TestStruct:=F_setToDefault_MyStruct();
I know, a lot more code, but no one can change the initial values in struct_NULL, and I think it´s much more easier to read and understand

Freeglut doesn't initialize when using it from Swift

I've tried to use the Freeglut library in a Swift 4 Project. When the
void glutInit(int *argcp, char **argv);
function is shifted to Swift, its declaration is
func glutInit(_ pargc: UnsafeMutablePointer<Int32>!, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!)
Since I don't need the real arguments from the command line I want to make up the two arguments. I tried to define **argv in the Bridging-Header.h file
#include <OpenGL/gl.h>
#include <GL/glut.h>
char ** argv[1] = {"t"};
and use them in main.swift
func main() {
var argcp: Int32 = 1
glutInit(&argcp, argv!) // EXC_BAD_ACCESS
glutInitDisplayMode(UInt32(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH));
glutCreateWindow("my project")
glutDisplayFunc(display)
initOpenGL()
glutMainLoop()
but with that I get Thread 1: EXC_BAD_ACCESS (code=1, address=0x74) at the line with glutInit().
How can I initialize glut properly? How can I get an UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>! so that it works?
The reason the right code in C char * argv[1] = {"t"}; does not work is because Swift imports fixed size C-array as a tuple, not a pointer to the first element.
But your char ** argv[1] = {"t"}; is completely wrong. Each Element of argv needs to be char **, but you assign char * ("t"). Xcode must have shown you a warning at first build:
warning: incompatible pointer types initializing 'char **' with an expression of type 'char [2]'
You should better take incompatible pointer types warning as error, unless you know what you are doing completely.
Generally, you should better not write some codes generating actual code/data like char * argv[1] = {"t"}; in a header file.
You can try it with Swift code.
As you know, when you want to pass a pointer to single element T, you declare a var of type T and pass &varName to the function you call.
As argcp in your code.
As well, when you want to pass a pointer to multiple element T, you declare a var of type [T] (Array<T>) and pass &arrName to the function you call.
(Ignoring immutable case to simplify.)
The parameter argv matches this case, where T == UnsafeMutablePointer<Int8>?.
So declare a var of type [UnsafeMutablePointer<Int8>?].
func main() {
var argc: Int32 = 1
var argv: [UnsafeMutablePointer<Int8>?] = [
strdup("t")
]
defer { argv.forEach{free($0)} }
glutInit(&argc, &argv)
//...
}
But I wonder if you really want to pass something to glutInit().
You can try something like this:
func main() {
var argc: Int32 = 0 //<- 0
glutInit(&argc, nil)
//...
}
I'm not sure if freeglut accept this, but you can find some articles on the web saying that this works in some implementation of Glut.

F# Class with Generics : 'constructor deprecated' error

I am trying to create a a class that will store a time series of data - organized by groups, but I had some compile errors so I stripped down to the basics (just a simple instantiation) and still can't overcome the compile error. I was hoping some one may have seen this issue before. Clas is defined as:
type TimeSeriesQueue<'V, 'K when 'K: comparison> = class
val private m_daysInCache: int
val private m_cache: Map<'K, 'V list ref > ref;
val private m_getKey: ('V -> 'K) ;
private new(getKey) = {
m_cache = ref Map.empty
m_daysInCache = 7 ;
m_getKey = getKey ;
}
end
So that looks OK to me (it may not be, but doesnt have any errors or warnings) - the instantiation gets the error:
type tempRec = {
someKey: string ;
someVal1: int ;
someVal2: int ;
}
let keyFunc r:tempRec = r.someKey
// error occurs on the following line
let q = new TimeSeriesQueue<tempRec, string> keyFunc
This construct is deprecated: The use
of the type syntax 'int C' and 'C
' is not permitted here. Consider
adjusting this type to be written in
the form 'C'
NOTE This may be simple stupidity - I am just getting back from holiday and my brain is still on time zone lag...
The compiler is just saying that you need to enclose parameters of the constructor in parentheses:
// the following should work fine
let q = new TimeSeriesQueue<tempRec, string>(keyFunc)
There are some other issues though - the constructor needs to be public (otherwise you cannot call it) and the parameter of keyFunc should be also in parentheses (otherwise, the compiler will think that the type annotation is for the result of the function):
let keyFunc (r:tempRec) = r.someKey
You may also consider using implicit constructor syntax which makes class declarations a lot simpler in F#. Parameters of the constructor automatically become available in the body of the class and you can declare (private) fields simply using let:
type TimeSeriesQueue<'V, 'K when 'K: comparison>(getKey : 'V -> 'K) =
let daysInCache = 7
let cache = ref Map.empty
member x.Foo() = ()

What does error conflicting types for '' mean?

i got an error that said "error: conflicting types for '____'. What does that mean?
Quickfix:
Make sure that your functions are declared once and only once before they are called. For example, change:
main(){ myfun(3.4); }
double myfun(double x){ return x; }
To:
double myfun(double x){ return x; }
main(){ myfun(3.4); }
Or add a separate function declaration:
double myfun(double x);
main(){ myfun(3.4); }
double myfun(double x){ return x; }
Possible causes for the error
Function was called before being declared
Function defined overrides a function declared in an included header.
Function was defined twice in the same file
Declaration and definition don't match
Declaration conflict in the included headers
What's really going on
error: conflicting types for ‘foo’ means that a function was defined more than once with different type signatures.
A file that includes two functions with the same name but different return types would throw this error, for example:
int foo(){return 1;}
double foo(){return 1.0;}
Indeed, when compiled with GCC we get the following errors:
foo.c:5:8: error: conflicting types for ‘foo’
double foo(){return 1.0;}
^
foo.c:4:5: note: previous definition of ‘foo’ was here
int foo(){return 1;}
^
Now, if instead we had a file with two function definitions with the same name
double foo(){return 1;}
double foo(){return 1.0;}
We would get a 'redefinition' error instead:
foo.c:5:8: error: redefinition of ‘foo’
double foo(){return 1.0;}
^
foo.c:4:8: note: previous definition of ‘foo’ was here
double foo(){return 1;}
^
Implicit function declaration
So why does the following code throw error: conflicting types for ‘foo’?
main(){ foo(); }
double foo(){ return 1.0; }
The reason is implicit function declaration.
When the compiler first encounters foo() in the main function, it will assume a type signature for the function foo of int foo(). By default, implicit functions are assumed to return integers, and the input argument types are derived from what you're passing into the function (in this case, nothing).
Obviously, the compiler is wrong to make this assumption, but the specs for the C (and thus Objective-C) language are old, cranky, and not very clever. Maybe implicitly declaring functions saved some development time by reducing compiler complexity back in the day, but now we're stuck with a terrible feature that should have never made it into the language. In fact, implicit declarations were made illegal in C99.
That said, once you know what's going on, it should be easy to dig out the root cause of your problem.
it's probably because your function "_" already exists in your library. It happened to me with this function:
I was using stdio.h
int getline (char s[ ] , int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
When I changed "getline" to "getlinexxx" and gcc compiled it:
int getlinexxx (char s[], int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
And the problem was gone
What datatype is '___'?
My guess is that you're trying to initialize a variable of a type that can't accept the initial value. Like saying int i = "hello";
If you're trying to assign it from a call that returns an NSMutableDictionary, that's probably your trouble. Posting the line of code would definitely help diagnose warnings and errors in it.