Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

The Gay Bean posted:

I think I'm just going to start making Cmake compile all of my dependencies with specific flags and git/svn versions.. would anybody hate me if I were their coworker?
Yes.
You might be okay if you include downloading in your automated setup though. But even then, getting a specific version kind of sucks because usually a newer version with the same flags will do the trick, so ideally what you want is an automatic download of the newest version, and build with specific flags.
Kind of like a packaging system, but less broken.
(And then you want a fallback to the last known working version if the build doesn't work.)

Adbot
ADBOT LOVES YOU

Zerf
Dec 17, 2004

I miss you, sandman

The Gay Bean posted:

I think I'm just going to start making Cmake compile all of my dependencies with specific flags and git/svn versions.. would anybody hate me if I were their coworker?

No.
In fact, we have deployed the same system where I work. We used to check in precompiled binaries for the external dependencies we use, but it becomes such a chore to maintain. New compiler or new version of the library? Sure, let's find whoever compiled the library to begin with and see if they remember if they did anything special before they compiled and committed the lib.

Nowadays we use CMakes ExternalProject_Add. It works decently, the first time you build from source it will compile all external dependencies. Then it won't do so until you either change something or remove your build output directory(even if you use "Full rebuild" in Visual Studio). It works well with CI tools, since they can remove build directories during nightly builds, guaranteeing that you can always build from source but still costing no time for devs. The command even has support for downloads, so you could have a branch that is always up to date to see if new versions break your build. It also has support for custom commands for configure/build/install, which lets you compile libraries the way the developers want you to.

The downside is, of course, that it's a CMake function and the syntax for using it is horrible.

Lean Six Ligma
Nov 26, 2005

Dirty Fuckin' Dangles, Boys
Stupid embedded question that's kicking my rear end on a lab assignment with a TI Launchpad. (MSP430G2553)

I know this isn't the homework help forum, but i figured it was worth a shot to get a fresh perspective on this...

The problem is to read from a temperature sensor (TMP36GZ) and turn on an LED on port 1.5 when the temperature rises above 2 degrees Fahrenheit from the temperature recorded at startup. Conversion to Fahrenheit needs to be done by calling a function. The TA's in charge of the lab already wrote the setup for the 10 bit ADC, we just have to fill in the rest. I cannot for the life of me get this to do anything other than sit there with the LED shining with no way to change it. I verified all of the wiring so it has to be a code problem.

code:
#include <msp430.h>
#include <math.h>

int value = 0, i = 0 ;
int light = 0;
int temp = 0;
int touch = 0;
int ADCReading [3];
int oldTouch = 0;
int tempInitialRead = 0;
int toggle = 0;
float tempF = 0;
float initTemp = 0;


void ConvertToF(void);
void ConfigureAdc(void);



int main(void)
{
	WDTCTL = WDTPW + WDTHOLD; 			// Stop WDT
	P1DIR |= ( BIT4 | BIT5); 			// set bits 4, 5, 6 as outputs
	P1DIR &= (~BIT0 |~BIT1 |~BIT2);		// set bits 0, 1, 2 as inputs

	P2DIR |= BIT0;						// set bit 0 as output
	ConfigureAdc();

	


	for (;;)
	{
		i = 0; temp = 0; light = 0; touch =0; // set all analog values to zsero
		//Reading ADC Values
		for (i=1; i<=5; i++)
		{
			ADC10CTL0 &= ~ENC;
			while (ADC10CTL1 & BUSY); //Wait while ADC is busy
			ADC10SA = (unsigned)&ADCReading[0];
			//RAM Address of ADC Data, must be reset every conversion
			ADC10CTL0 |= (ENC | ADC10SC); //Start ADC Conversion
			while (ADC10CTL1 & BUSY); //Wait while ADC is busy
			light += ADCReading [0]; touch += ADCReading [1]; temp += ADCReading[2];
		}


		light = light/5;
		touch = touch/5;
		temp = temp/5;
		
		ConvertToF(); //convert input from temp sensor to deg F
		
		//VALUE OF TEMP ON STARTUP ***************************************
		if (tempInitialRead == 0) // have we read the temp at startup?
		{
			initTemp = tempF;		// temp @ startup
			initTemp = (initTemp + 2);	//add 2 for convenience later
			tempInitialRead++;		//turn this loop off after one run
		}
		 		
		/*here goes all of the other stuff like a light sensor and a touch
		*switch, got those working perfectly...*/
			
		
		//AIR CONDITIONER ************************************************
		if (tempF >= initTemp)
		{
			P1OUT &= (~BIT5);
			__delay_cycles(200);
		}
		else
		{
			P1OUT |= ( BIT5);
			__delay_cycles(200);
		}



	
	}
}

void ConvertToF(void)
{
	/* converting from 10-bit ADC value to a fahrenheit temperature;
	* This is assuming a 3.3V Vcc*/
	tempF = ((9.0/5.0)*((((temp) * (3300.0/1024.0))-500.0)/10.0)+32.0);
}


void ConfigureAdc(void)
{
	ADC10CTL1 = INCH_2 | CONSEQ_1; // A2 + A1 + A0, single sequence
	ADC10CTL0 = ADC10SHT_2 | MSC | ADC10ON;
	while (ADC10CTL1 & BUSY);
	ADC10DTC1 = 0x03; // 3 conversions
	ADC10AE0 |= (BIT0 | BIT1 | BIT2); // ADC10 option select
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
	__bic_SR_register_on_exit(CPUOFF);
}

What am I missing?

Lean Six Ligma fucked around with this message at 03:51 on Nov 6, 2014

sarehu
Apr 20, 2007

(call/cc call/cc)

Pixelated posted:

What am I missing?

Try running a simple program that sets and unsets BIT5 on P1OUT and see what happens.

TheFreshmanWIT
Feb 17, 2012
code:
P1OUT |= ( BIT5);
I might be reading it wrong, but it looks like the line above will not turn the light OFF when the temp is below 2+ the starting value, it'll actually just cycle it every time, right? It'll appear ON, but be turning on/off very rapidly.

astr0man
Feb 21, 2007

hollyeo deuroga

TheFreshmanWIT posted:

code:
P1OUT |= ( BIT5);
I might be reading it wrong, but it looks like the line above will not turn the light OFF when the temp is below 2+ the starting value, it'll actually just cycle it every time, right? It'll appear ON, but be turning on/off very rapidly.

Assuming his macros work correctly that should set bit5 on p1out to 1 whenever tempF < initTemp. |= doesn't make it cycle between 1 and 0. Whether bit5 is supposed to be a 1 or a 0 to turn the on the led is unclear.

Lean Six Ligma
Nov 26, 2005

Dirty Fuckin' Dangles, Boys
It needs to be a 1 to turn the LED on. The first thing I did after breadboarding the little circuit was make a program to make the three LEDs sweep back and forth like KITT/cylon :awesomelon:

Also holding a hot soldering iron near the sensor didn't turn the LED off, so even if I have it backwards, i'm not sure what's going on...

Lean Six Ligma fucked around with this message at 18:17 on Nov 6, 2014

astr0man
Feb 21, 2007

hollyeo deuroga

Pixelated posted:

It needs to be a 1 to turn the LED on.

C++ code:
		if (tempF >= initTemp)
		{
			P1OUT &= (~BIT5);
			__delay_cycles(200);
		}
		else
		{
			P1OUT |= ( BIT5);
			__delay_cycles(200);
		}
This does appear to be backwards then. That doesn't solve your problem as to why it still doesn't turn the led off with the soldering iron. I would guess that you are reading the temperature incorrectly. Do you have a debugger or something you can use to verify that your voltage to fahrenheit conversion is actually working?

Lean Six Ligma
Nov 26, 2005

Dirty Fuckin' Dangles, Boys
Switching the if-else around made it work perfectly. not sure what was going on there or how I missed that it was backwards...

Fun stuff: if the laptop powering the MCU is plugged in, the switch to turn on another LED makes this one toggle rapidly. If i'm on battery, it works perfectly

:psyduck:

pretty sure that's an electronics problem, and not software, though. Works perfectly otherwise.

Thanks for the help!

Mellow_
Sep 13, 2010

:frog:

Pixelated posted:

Stupid embedded question that's kicking my rear end on a lab assignment with a TI Launchpad. (MSP430G2553)

I know this isn't the homework help forum, but i figured it was worth a shot to get a fresh perspective on this...

The problem is to read from a temperature sensor (TMP36GZ) and turn on an LED on port 1.5 when the temperature rises above 2 degrees Fahrenheit from the temperature recorded at startup. Conversion to Fahrenheit needs to be done by calling a function. The TA's in charge of the lab already wrote the setup for the 10 bit ADC, we just have to fill in the rest. I cannot for the life of me get this to do anything other than sit there with the LED shining with no way to change it. I verified all of the wiring so it has to be a code problem.

code:
void ConvertToF(void)
{
	/* converting from 10-bit ADC value to a fahrenheit temperature;
	* This is assuming a 3.3V Vcc*/
	tempF = ((9.0/5.0)*((((temp) * (3300.0/1024.0))-500.0)/10.0)+32.0);
}
What am I missing?

I know it sounds so simple, but are you supplying the TMP36GZ with +3.3V on it's Vcc? This formula assumes so, and if you're feeding it +5V it's going to output wrong.

EDIT: Alternatively consider posting in the Embedded Systems Megathread.

Mellow_ fucked around with this message at 22:45 on Nov 6, 2014

The Gay Bean
Apr 19, 2004
Does anybody know of a library where you can open multiple streams for input and output inside of a compressed archive? The idea would be an archive format for which a series of images and text files can be stored.. sort of like a docx file.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
libarchive?

The Gay Bean
Apr 19, 2004
That should do the trick, thanks.

raminasi
Jan 25, 2005

a last drink with no ice
I'm looking at a codebase that routinely calls function pointers with the wrong number of arguments. It compiles as C, but not as C++. Is there some legitimate reason for this to compile?

FamDav
Mar 29, 2008

GrumpyDoctor posted:

I'm looking at a codebase that routinely calls function pointers with the wrong number of arguments. It compiles as C, but not as C++. Is there some legitimate reason for this to compile?

are the function pointers of the form T()? in c a function of that form can take as many arguments as you would like to supply to it, whereas in c++ that is explicitly a function that takes no arguments.

otherwise, you're gonna have to cast function pointers which means undefined behavior. i would think in that case youd be seeing runtime errors, though.

EDIT: just to double check, the functions youre taking the address of arent defined with old style function declarations are they? that would definitely not compile in c++ but will compile in c given the correct flags AND will allow you to pass whatever amount of arguments you want because old style declarations are insanity

FamDav fucked around with this message at 00:39 on Nov 8, 2014

raminasi
Jan 25, 2005

a last drink with no ice

FamDav posted:

are the function pointers of the form T()? in c a function of that form can take as many arguments as you would like to supply to it, whereas in c++ that is explicitly a function that takes no arguments.

otherwise, you're gonna have to cast function pointers which means undefined behavior. i would think in that case youd be seeing runtime errors, though.

Yep, that's it. My problem is that I need to compile this as C++ and they're relying on this behavior all over the place.

FamDav
Mar 29, 2008

GrumpyDoctor posted:

Yep, that's it. My problem is that I need to compile this as C++ and they're relying on this behavior all over the place.

i honestly havent had to actually do this in the wild, but here's my understanding of how to get this done. i'm assuming this is a library? if so:

* compile the library via your c compiler
* wherever you are including headers from the c lib, wrap the macros in "extern "C" { #include "butts.h" }". this is where you find out if they were doing this in their headers :[.
* compile and link the rest of your program with your c++ compiler

if all goes correctly, your c code is compiled correctly, your c++ code calls into it with the correct calling conventions, and everybody ends up happy.

raminasi
Jan 25, 2005

a last drink with no ice

FamDav posted:

i honestly havent had to actually do this in the wild, but here's my understanding of how to get this done. i'm assuming this is a library? if so:

* compile the library via your c compiler
* wherever you are including headers from the c lib, wrap the macros in "extern "C" { #include "butts.h" }". this is where you find out if they were doing this in their headers :[.
* compile and link the rest of your program with your c++ compiler

if all goes correctly, your c code is compiled correctly, your c++ code calls into it with the correct calling conventions, and everybody ends up happy.

I know how to link C and C++ code. I want to compile it as C++ so I can include it in a mixed-mode C++/CLI assembly.

Qwertycoatl
Dec 31, 2008

FamDav posted:

are the function pointers of the form T()? in c a function of that form can take as many arguments as you would like to supply to it, whereas in c++ that is explicitly a function that takes no arguments.

otherwise, you're gonna have to cast function pointers which means undefined behavior. i would think in that case youd be seeing runtime errors, though.


It's okay to cast function pointers to other kinds of function pointers, so long as you never call the function through a pointer of the wrong type. So when you actually want to call the function, you can cast it to the correct type just before you use it:
code:
typedef void (*void_func_ptr)();
typedef void (*int_func_ptr)(int);

void my_function(int x) {}

void_func_ptr my_shitty_pointer = (void_func_ptr)my_function;
...
((int_func_ptr)my_shitty_pointer)(27);

Evrart Claire
Jan 11, 2008
Trying to relearn some C (my previous background in it was real basic to begin with) because my professor for my math undergrad capstone wants to use the C99 standard for part of it.

I'm trying to make a C function that can take a mathematical vector function as the 3 separate components, ie: Vector-A = <Ax,Ay,Az> where each of those 3 are 3-variable mathematic functions that can get pretty complex. I don't really know though how I should handle the function inputs so that they can be parsed as a mathematical expression that calculations can be done on where x, y, z are all arrays of values.

Evrart Claire fucked around with this message at 02:35 on Nov 9, 2014

sarehu
Apr 20, 2007

(call/cc call/cc)

Zerilan posted:

Trying to relearn some C (my previous background in it was real basic to begin with) because my professor for my math undergrad capstone wants to use the C99 standard for part of it.

I'm trying to make a C function that can take a mathematical vector function as the 3 separate components, ie: Vector-A = <Ax,Ay,Az> where each of those 3 are 3-variable mathematic functions that can get pretty complex. I don't really know though how I should handle the function inputs so that they can be parsed as a mathematical expression that calculations can be done on where x, y, z are all arrays of values.

What is a mathematic function?

So Ax, Ay, and Az are functions from R^3 to R (or C^3 to C?). Why do you need to parse them as mathematical expressions in order to evaluate them? Wouldn't they just be C functions, that take a value in R^3 (or C^3) as input and return a value in R (or C)?

What is x, y, and z? You didn't mention them before you suddenly said they're arrays of values. What kind of value? Are you saying that the functions Ax, Ay, and Az would have different inputs (they being x, y, and z), because if so I think that's wrong, because they're computing components of the function "Vector-A" which means they'd all take the same input value (a point in R^3 (or C^3)).

sarehu fucked around with this message at 10:43 on Nov 9, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

FamDav posted:

* wherever you are including headers from the c lib, wrap the macros in "extern "C" { #include "butts.h" }". this is where you find out if they were doing this in their headers :[.

Never do this.

GrumpyDoctor posted:

I know how to link C and C++ code. I want to compile it as C++ so I can include it in a mixed-mode C++/CLI assembly.

There's no way to get the behavior you want in C++ without source changes, but you can certainly follow this sage advice:

Qwertycoatl posted:

It's okay to cast function pointers to other kinds of function pointers, so long as you never call the function through a pointer of the wrong type. So when you actually want to call the function, you can cast it to the correct type just before you use it:

You can write a variadic template to automate casting to the right function type, although I don't know if the C++/CLI frontend supports those. But you'll still need to modify both the original declaration and the definition to use C linkage, because parameter types distinguish functions in C++.

But you will probably be happier if you just bite the bullet and bring that source base kicking and screaming into the late 1980s by using proper function prototypes. Fortunately, that should be extremely scriptable.

Evrart Claire
Jan 11, 2008
Ok yeah, let me try wording that better.

I need to write a function to calculate finite difference approximations in C99 to find the curl of a Vector. So I need to take a vector-valued function in R^3 (ie: Vector-A = AxI + AyJ +AzK where I,J,K are the unit vectors in the x y z dimensions, and Ax,Ay,Az are each something like "x^3*y^3+z^4" or an "r^2+r+C" polynomial where r=sqrt(x^2+y^2+z^2), plot each point of the vector using a large range of R^3 points (x,y,z since using Cartesian coords), based on a min-max range of each of them and a given spacing (ie: x from -2 to 2 with .01 spacing), and use the values generated from that to approximate the curl of the vector at each set of values.

Function needs to take in the vector-valued function, or each R->R component separately, the domain of x,y,z points to calculate it at (so the max/min of x, y, and z), and the spacing between points for each of x,y,z, and output the curl of the vector at each r^3 point.

Don't have any problems with doing the calculations in the function, but I don't really know how to handle the function inputs.

sarehu
Apr 20, 2007

(call/cc call/cc)
Point of order: You keep saying "vector" in places where you mean "vector field". (e: And I assume by "each R->R component" you mean "each R->R^3 component".)

Presumably you would have your function prototype be

return_type do_curl_stuff(vec3 (*vectorA)(vec3), ...other parameters...)

where vec3 is your 3 dimensional vector type, defined by something such as typedef struct { double x, y, z; } vec3; or typedef struct { double coords[3]; } vec3;.

sarehu fucked around with this message at 11:29 on Nov 9, 2014

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

GrumpyDoctor posted:

I'm looking at a codebase that routinely calls function pointers with the wrong number of arguments. It compiles as C, but not as C++. Is there some legitimate reason for this to compile?

As others have said, this is how old school C rocked

I think the closest equivalent of int foo() in C++ would be int foo(...). It's not standards compliant like, at all, but in this particular case I think it's acceptable. Make sure to test it with all possible combinations of argument types, especially pointers, but in this one case where you have one compiler, one platform, one codebase, it's OK. Well, it will work for native code, I'm not sure how managed code will like it...

OK, I tried. It works, both in managed and native mode. This code gives the same output when compiled with or without /clr:

C++ code:
#include <stdio.h>

int aaa(int x, long long y, void *z)
{
	printf("%d %lld %p\n", x, y, z);
	return 1234;
}

static int ccc = 0;

int main(void)
{
	printf("%d\n", aaa(-1000000000, -1000000000000, &ccc));

	int (*bbb)(...) = (int (*)(...))&aaa;
	printf("%d\n", bbb(-1000000000, -1000000000000, &ccc));

	return 0;
}
It's better if you don't see what it compiles to in C++/CLI, though...

raminasi
Jan 25, 2005

a last drink with no ice

rjmccall posted:

Never do this.


There's no way to get the behavior you want in C++ without source changes, but you can certainly follow this sage advice:


You can write a variadic template to automate casting to the right function type, although I don't know if the C++/CLI frontend supports those. But you'll still need to modify both the original declaration and the definition to use C linkage, because parameter types distinguish functions in C++.

But you will probably be happier if you just bite the bullet and bring that source base kicking and screaming into the late 1980s by using proper function prototypes. Fortunately, that should be extremely scriptable.

A full rewrite is off the table for a bunch of reasons. And "just make it use the right prototypes" is going to be annoyingly difficult, because they weren't just being fast-and-loose with types. It looks like they were actually using these like dynamic typing, but for function pointers. The same variable will be called different ways in different parts of the code depending on what happened to be previously stored in it, so just changing a type somewhere won't be sufficient. As I posted in the coding horrors thread, I found this bad boy:
C code:
typedef struct {
	char  *funame;			/* function name */
	int  flags;			/* type flags */
#ifdef FUN_ARGLIST
	int  (*funp)(FUN_ARGLIST);	/* pointer to function */
#else
	int  (*funp)();			/* pointer to function */
#endif
}  FUN;
Whatever you want to argue about where that falls on the clever-horror scale, FUN_ARGLIST is never defined anywhere, and they just rely on this behavior of argumentless function pointers to make everything work. (And this particular struct isn't the only place this comes up.)

At this point I'm probably going to just leave this in its own C DLL and dynamically linking it in. The only reason I wanted a mixed-mode assembly was to avoid having a jillion DLLs that the program needs to run.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

GrumpyDoctor posted:

C code:
typedef struct {
	char  *funame;			/* function name */
	int  flags;			/* type flags */
#ifdef FUN_ARGLIST
	int  (*funp)(FUN_ARGLIST);	/* pointer to function */
#else
	int  (*funp)();			/* pointer to function */
#endif
}  FUN;
Whatever you want to argue about where that falls on the clever-horror scale, FUN_ARGLIST is never defined anywhere, and they just rely on this behavior of argumentless function pointers to make everything work. (And this particular struct isn't the only place this comes up.)

C code:
#define FUN_ARGLIST ...
You'll have to add a cast everywhere funp is assigned. You can't really replace the naked function pointer type with a wrapper class that does the cast for you, because that requires variadic templates, which the Microsoft compiler doesn't support

I will not in any way pretend this isn't terrible, but in your specific combination of compiler and environment it will work

Evrart Claire
Jan 11, 2008

sarehu posted:

Point of order: You keep saying "vector" in places where you mean "vector field". (e: And I assume by "each R->R component" you mean "each R->R^3 component".)

Presumably you would have your function prototype be

return_type do_curl_stuff(vec3 (*vectorA)(vec3), ...other parameters...)

where vec3 is your 3 dimensional vector type, defined by something such as typedef struct { double x, y, z; } vec3; or typedef struct { double coords[3]; } vec3;.

Yeah, I meant vector field. By each component I think I meant R^3->R (ie: Ax takes a point, outputs the x component of the vector that's at that point in the vector field)

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

OK, I found the library you're using, and you don't need variadic templates, all the functions have between one and two arguments. Also the code is very polite and dereferences function pointers before calling them, so you don't even need operator(). Add this to otypes.h, before FUN:
C++ code:
struct ofunp
{
private:
    int (* m_pfun)(...);

public:
    template<class ArgT>
    const ofunp& operator=(int (* pfun)(ArgT))
    {
        m_pfun = (int (*)(...))pfun;
        return *this;
    }

    template<class Arg1T, class Arg2T>
    const ofunp& operator=(int (* pfun)(Arg1T, Arg2T))
    {
        m_pfun = (int (*)(...))pfun;
        return *this;
    }

    auto operator*() const -> decltype(*m_pfun)
    {
        return *m_pfun;
    }
};
and then change the definition of FUN to:
C++ code:
typedef struct {
        char  *funame;                  /* function name */
        int  flags;                     /* type flags */
        ofunp funp;                     /* pointer to function */
}  FUN;
It won't be terribly efficient though, variadic calls go through native code

Have you tried compiling the library as a native static library, and then linking to it?

raminasi
Jan 25, 2005

a last drink with no ice

hackbunny posted:

Have you tried compiling the library as a native static library, and then linking to it?

Actually, no, I haven't. I have no idea why I didn't think to do that.

raminasi
Jan 25, 2005

a last drink with no ice
Another question: Why does this
C code:
#ifdef _WIN32
extern double	erf(double x);
extern double	erfc(double x);
#endif
emit an "inconsistent dll linkage" warning for each declaration? I'm compiling as a static library.

sarehu
Apr 20, 2007

(call/cc call/cc)

Zerilan posted:

By each component I think I meant R^3->R

Erm.. yeah.

KaneTW
Dec 2, 2011

GrumpyDoctor posted:

Another question: Why does this
C code:
#ifdef _WIN32
extern double	erf(double x);
extern double	erfc(double x);
#endif
emit an "inconsistent dll linkage" warning for each declaration? I'm compiling as a static library.

Can you post the exact error?

Not Dave
Aug 9, 2009

ATAI SUPER DRY IS
BREWED FROM QUALITY
ENGREDIENTS BY USING
OUR PURE CULTURE
YEAST AND ADVANCED
BREWING TECHNIQUES.
I have a question, and it doesn't necessarily need to be good form C but just needs to run. I have two files, a .c with a main and a .h that I need to add mutex/cv logic to in different ways for parallelization (using pthreads but I don't think that matters for what I need to know). The .h has one function that the thread uses with the parallelization stuff missing. The .c has everything else to make it work, and I shouldn't edit it at all.

How do I initialize the mutex and CV so it'll be global, or at least shared by all the threads using the function in the header? I know for the ints I'm using as counters it's possible to declare and define them globally in the header since I'm only going to have one .c, avoiding collision, but the the mutex and CV I need to call the initialization, obviously not in the function for the threads, but not in the .c's main either.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Thread libraries usually give you macros that can be used to constant-initialize mutexes and so on. For pthreads, these are PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER.

pseudorandom name
May 6, 2007

Which are normally used at global or static scope in source files, not headers, but will probably work fine in this homework instance.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

GrumpyDoctor posted:

Another question: Why does this
C code:
#ifdef _WIN32
extern double	erf(double x);
extern double	erfc(double x);
#endif
emit an "inconsistent dll linkage" warning for each declaration? I'm compiling as a static library.

Are you getting this warning when you compile the library, or when you compile your C++/CLI application? because if it's the latter, you probably do need to wrap the library's headers with extern "C" {}

But yes, post the exact error

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

pseudorandom name posted:

Which are normally used at global or static scope in source files, not headers, but will probably work fine in this homework instance.

Right. Understand that this assignment is not following the accepted best practice for splitting a program up across multiple files. Understand it, hold your nose, and act like your "header" is just another ordinary source file.

fritz
Jul 26, 2003

Does anybody have a favourite c++ logging package? I'm thinking of going with glog, just for ease of use in getting started, but I'd eventually like to be able to hook it into some kind of remote logging facility (we currently have flume for another project, and if we could optionally send log events over the network that would be perfect).

Adbot
ADBOT LOVES YOU

MrMoo
Sep 14, 2000

You can send google-logging over the network with sawbuck, of course there are no server implementations. I just lifted the code straight from the Chromium repo, the "glog" package doesn't look like it helps much.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply