Signature difference in openGlShaderSource between OpenGL ES 2 revisions - opengl-es

I've noticed that the signature of openGLShaderSource has changed:
If you look at gl2.h from http://www.khronos.org/registry/gles/ (for me at rev 16803), the signature reads:
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
Now, on an older revision of that file (rev 10602), or when looking at the desktop version of that function, the signature reads:
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
note the missing "const" for the string parameter...
Has anyone an idea how one could detect this and keep backwards compatibility? As far as I can see, there is no "revision" macro defined, that one could check to use one version or the other.
Background information: I'm trying to compile WebKit for an embedded platform that ships the new gl2.h header. And webkit has this:
typedef void (*glShaderSourceType) (GLuint, GLsizei, const char**, const GLint*);
in http://opensource.apple.com/source/WebCore/WebCore-1298/platform/graphics/cairo/OpenGLShims.h and thus fails to compile when it tries to assign the glShaderSource function pointer to a glShaderSourceType-variable with the new gl2.h version...

Thanks to the hint by Nicol Bolas! This seems to compile:
void foo(const char* const*) {}
void bar(const char**) {}
typedef void (*ftype)(const char**);
int main() {
ftype f1 = reinterpret_cast(foo);
ftype f2 = bar;
return 0;
}

Related

how to fix wrong GCC ARM startup code pointer to initialized and zero variables?

[skip to UPDATE2 and save some time :-)]
I use ARM Cortex-M4, with CMSIS 5-5.7.0 and FreeRTOS, compiling using GCC for ARM (10_2021.10)
My variables are not initialized as they should.
My startup code is pretty simple, the entry point is the reset handler (CMSIS declared startup_ARMCM4.s as deprecated and recommend using the C code startup code so this is what I do).
Here is my code:
__attribute__((__noreturn__)) void Reset_Handler(void)
{
DataInit();
SystemInit(); /* CMSIS System Initialization */
main();
}
static void DataInit(void)
{
typedef struct {
uint32_t const* src;
uint32_t* dest;
uint32_t wlen;
} __copy_table_t;
typedef struct {
uint32_t* dest;
uint32_t wlen;
} __zero_table_t;
extern const __copy_table_t __copy_table_start__;
extern const __copy_table_t __copy_table_end__;
extern const __zero_table_t __zero_table_start__;
extern const __zero_table_t __zero_table_end__;
for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
for(uint32_t i=0u; i<pTable->wlen; ++i) {
pTable->dest[i] = pTable->src[i];
}
}
for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
for(uint32_t i=0u; i<pTable->wlen; ++i) {
pTable->dest[i] = 0u;
}
}
}
__copy_table_start__, __copy_table_end__ etc. have the wrong values an so no data is copied to the appropriate place in RAM.
I tried adding __libc_init_array() before DataInit(), as suggested in this answer, and remove the nostartfiles flag from the linker, but at some point __libc_init_array() jumps to an illegal address and I get a HardFault interrupt.
Is there a different method to fix it? maybe one where I can use the nostartfiles flag?
UPDATE:
Looking at the memory, where __copy_table_start__ is located, I see the data there is valid (even without the use of __libc_init_array()). It seems that pTable doesn't get the correct value.
I tried using __data_start__, __data_end__, __bss_start__, __bss_end__ and __etext instead of the above variables, in the linker file it is said they can be used in code without definition, but they cannot (maybe that's a clue?). In any case they didn't work either.
UPDATE2:
found the actual problem
all struct members get the same value (modifying one changes all others), it happens with every struct. I have no idea how this is possible. In other words the value of __copy_table_start__.src is, for example, 0x14651234, __copy_table_start__.dest is 0x00100000, and __copy_table_start__.wlen is 0x0365. When looking at pTable all members are 0x14651234.

Using coeffRef with const CwiseUnaryView - Failing when multiplying two CWiseUnaryViews

I'm having some trouble when using coeffRef() with a CWiseUnaryView function, but only when the function is declared as const
Reproducible example:
#include <Eigen/Core>
struct dummy_Op {
EIGEN_EMPTY_STRUCT_CTOR(dummy_Op)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const double&
operator()(const double &v) const { return v; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE double&
operator()(double &v) const { return v; }
};
void foo(Eigen::MatrixXd &out)
{
//Compiles
Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> view(out);
view.coeffRef(0,0);
//Doesn't Compile
const Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> const_view(out);
const_view.coeffRef(0,0);
}
Returns:
<source>: In function 'void foo(Eigen::MatrixXd&)':
<source>:21:28: error: passing 'const Eigen::CwiseUnaryView<dummy_Op,
Eigen::Matrix<double, -1, -1> >' as 'this' argument discards qualifiers
[-fpermissive]
const_view.coeffRef(0,0);
^
In file included from /opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/Core:413,
from <source>:1:
/opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/src/Core/DenseCoeffsBase.h:340:33: note:
in call to 'Eigen::DenseCoeffsBase<Derived, 1>::Scalar&
Eigen::DenseCoeffsBase<Derived, 1>::coeffRef(Eigen::Index, Eigen::Index)
[with Derived = Eigen::CwiseUnaryView<dummy_Op, Eigen::Matrix<double,
-1, -1> >; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = double; Eigen::Index = long int]'
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
^~~~~~~~
Compiler returned: 1
Compiler explorer: https://godbolt.org/z/kPHPuC
The side-effect of this, is that the multiplication of two (non-const) CWiseUnaryViews also fails, see example here: https://godbolt.org/z/JYQb3d
The bottom line is that you're calling a non-const method of a constant instance. The (first) coeffRef that is being called is the one (and only) in DenseCoeffsBase.h (DenseCoeffsBase<Derived, WriteAccessors>), which is not const qualified. The DenseCoeffsBase<Derived, ReadOnlyAccessors> class does not have a coeffRef method. You can get around this error (and get a warning) if you enable the -fpermissive compiler flag.
In the dense case, you probably want to use the operator()(Index, Index) method anyway, which does have a const qualified version. I just noticed the documentation explicitly says to use that method anyway, even for the non-const version. This is obviously not going to return a const reference, but at least in your example as a double, it shouldn't matter too much.
CwiseUnaryView is intended to be used for L-value like expression, e.g.,
MatrixXcd A;
A.real() = something; // `A.real()` is writable
If you want to apply an element-wise functor and use it as an R-value, you should use CwiseUnaryOp instead:
void foo(Eigen::MatrixXd &out)
{
Eigen::CwiseUnaryOp<dummy_Op, Eigen::MatrixXd> view1(out);
// shorter:
auto view2 = out.unaryExpr(dummy_Op());
Eigen::MatrixXd result = view1 * view2;
// or directly write: out.unaryExpr(dummy_Op()) * out.unaryExpr(dummy_Op());
}

exposing a function with 2D slice as a parameter in a c-shared library (to be used in Java via JNA and C)

I am trying to write a simple matrix operations API using go and expose the APIs as a shared library. This shared library will be used from Java(using JNA) and from C.
The documentation is very sparse about using any data type beyond simple int or string as function parameters.
My requirement is to expose functions with 1 or more 2D slices as parameters AND also as return types. I am not able to figure out if such a thing is supported.
Is this possible? Are there any examples for this?
I think the key point is to have a look to the c bindings of slice,string and int generated by go build tool. I not tried 2D slice, but it should no different to 1D slice with unsafe pointer converter, maybe just be one more time allocation and convertion.
I'm not sure it's the best way, but here's the example for 1D slice:
the go part:
import "C"
//export CFoo
func CFoo(content []byte) string{
var ret []byte
//blablabla to get ret
cbuf := unsafe.Pointer(C.malloc(C.size_t(len(ret))))
C.memcpy(cbuf, unsafe.Pointer(&ret[0]), C.size_t(len(ret)))
var finalString string
hdr := (*reflect.StringHeader)(unsafe.Pointer(&finalString))
hdr.Data = uintptr(unsafe.Pointer(cbuf))
hdr.Len = len(ret)
return finalString
}
compile with -buildmode=c-shared, to get libmygo.so.
I not know JNA, expecting it like JNI. the JNI part as well as pure C part:
#include <stdio.h>
#include <jni.h>
#include <string.h>
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt32 GoInt;
typedef GoUint32 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
JNIEXPORT JNICALL jbyteArray Java_com_mynextev_infotainment_app_myev_Native_foo(JNIEnv* env, jobject obj,jbyteArray content){
JNIEnv ienv = *env;
void * Ccontent = ienv->GetByteArrayElements(env, content, 0);
int Lcontent = ienv->GetArrayLength(env, content);
GoSlice Gcontent = {Ccontent, Lcontent, Lcontent};
if(!gret.n){
printf("jni CDoAESEnc");
return NULL;
}
jbyteArray ret = ienv->NewByteArray(env, gret.n);
ienv->SetByteArrayRegion(env, ret, 0, gret.n, gret.p);
free((void*)gret.p);
ienv->ReleaseByteArrayElements(env, content, Ccontent, JNI_ABORT);
return ret;
}
build it with libmygo.so.
finally you get two so files. one for C which can be used standalone; one for Java which must be used with libmygo.so together.

VC++ WINAPI Form: Identifier Not Found (C3861 Error)

I'm working on a port from some old Delphi code to VC++ 2013, and I'm encountering an error that I feel should be an easy fix but cannot for the life of me figure out...
The problem is this: I have a number of common utility functions in a local file Utils.h that I am deploying as part of a windows form. Most (90%) of the functions in this header work as normal. GetMsg(...), however, throws a C3861 Identifier not found error...
Utils.h (snippet): GetMsg declared at bottom
#pragma once
/*------------------------------------------------------------------------*
Includes:
*------------------------------------------------------------------------*/
using namespace std;
/*------------------------------------------------------------------------*
Constants:
*------------------------------------------------------------------------*/
#define GET_MSG_TIMEOUT 2
/*------------------------------------------------------------------------*
Typedefs, Structs, Enums:
*------------------------------------------------------------------------*/
typedef union
{
unsigned long ui32;
unsigned char ui8[4];
} UI32_UI8;
typedef union
{
unsigned short ui16;
unsigned char ui8[2];
} UI16_UI8;
typedef union
{
float f;
unsigned char ui8[4];
} F_UI8;
typedef struct
{
string sName;
string sVersion;
string sCompany;
string sCopyright;
} PRODUCT_INFORMATION;
/*------------------------------------------------------------------------*
Prototypes:
*------------------------------------------------------------------------*/
unsigned short SwapShort(unsigned short aShort);
float SwapFloat(float aFloat);
unsigned long SwapLong(unsigned long aLong);
unsigned int ReadLine(unsigned char *msgBuf, SerialPort^ Hdl, bool ReturnLF);
void __stdcall FillTheBuffer(char *buf, String sss, int length);
string __stdcall FillTheString(string sss, int length);
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf);
GetMsg Definition in Utils.cpp:
//---------------------------------------------------------
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf)
{
...
}
And, finally, GetMsg usage in form file:
#include "Utils.h"
...
void MainForm::UploadButton_Click
(System::Object^ object, System::EventArgs^ e)
{
...
SwapShort(1); //Works fine, also declared in Utils.h
GetMsg(spCom, inBuf); //C3861 ERROR
...
}
Where spCom is a (SerialPort^) contained, configured, and opened within the windows form. inBuf is a simple array of characters (char*) to buffer the input. I've tried renaming the function, thinking that there may have been an unintentional conflict / overload in other files, to no avail.
Any advice? Thanks, in advance
Solved the problem -- As it turns out I needed to be more explicit in my function definitions. Changing the declaration to read
GetMsg(System::IO::Ports::SerialPort^ Hdl, unsigned char *msgBuf)
eliminated the C3861 error. It would seem that the lack of a specific namespace on the declaration passed Intellisense but confused the compiler, rendering it unable to determine which prototype to use with the function call.

I found some weird function signature in glibc, can anyone expain it to me?

#include <string.h>
#include <memcopy.h>
#include <pagecopy.h>
#undef memcpy
void *
memcpy (dstpp, srcpp, len)
void *dstpp;
const void *srcpp;
size_t len;
{
unsigned long int dstp = (long int) dstpp;
unsigned long int srcp = (long int) srcpp;
...
This is our familiar lib function memcpy's implementation, but I don't recognize its
signature and I've never seen it before. Can anyone tell me what it is?
This is our familiar lib function memcpy's implementation, but I don't recognize its signature
Which aspect of it don't you recognize? Is it the fact that it is written in K&R (pre-ANSI) C, or something else? Would you have recognized it if it was written that way instead:
void *
memcpy(void *dstpp, const void *srcpp, size_t len)
{
...
}

Resources