Download

Getting very angry at Plugin Development

But that’s the thing, I didn’t make any code at all. I did exactly as you asked me to and generated a project to put in Visual Studio.

So I just did the following:


// Some copyright should be here...
#pragma once

#include "..\Public\RandomNumberGeneratorsPlugin.h"

// You should place include statements to your module's private header files here.  You only need to
// add includes for headers that are used in most of your module's source files though.

And it solved the issue. Now I just have those two command line errors.

I might not be following, but did the above error not specifically say to use forward slashes instead of backwards? ‘/’ instead of ‘’ in your include paths. Might work :slight_smile:

The “access denied” error mostly happens to me if I try to rebuilt it while I’m also still running it - even if it’s just the UE crash reporter that’s still open.

The best way to run it is actually through the local debugger, not a rebuild. It’ll automatically build any changes for you and it makes tracing out errors easier, plus it preserves your output log after you crash out or quit. I don’t launch any other way now.

I can’t include <iostream> as it’s not in any of the Modules (???)

It should work.

Okay seems it didn’t matter any way. For what I need it to do I don’t need the <iostream> include even though it confuses the shat out of me as to why it didn’t work.
Now I have a file where some uses of NULL are underlined as undefined while others are not in the same file.


/**
 * C++ Mersenne Twister wrapper class written by
 * Jason R. Blevins <jrblevin@sdf.lonestar.org> on July 24, 2006.
 * Based on the original MT19937 C code by
 * Takuji Nishimura and Makoto Matsumoto.
 */

/* 
   A C-program for MT19937, with initialization improved 2002/1/26.
   Coded by Takuji Nishimura and Makoto Matsumoto.

   Before using, initialize the state by using init_genrand(seed)  
   or init_by_array(init_key, key_length).

   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
   All rights reserved.                          

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

     1. Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.

     2. Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.

     3. The names of its contributors may not be used to endorse or promote 
        products derived from this software without specific prior written 
        permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   Any feedback is very welcome.
   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/

#include <cassert>

#include "mt.h"

/**
 * Constructor
 */
MersenneTwister::MersenneTwister(void):
    mt_(new unsigned long[N]), mti_(N+1),
    init_key_(NULL), key_length_(0), s_(0),
    seeded_by_array_(false), seeded_by_int_(false)
{
    unsigned long init[4] = { 0x123, 0x234, 0x345, 0x456 };
    unsigned long length = 4;
    init_by_array(init, length);
}

/**
 * Destructor
 */
MersenneTwister::~MersenneTwister(void)
{
    assert(mt_ != NULL);
    delete] mt_;
    mt_ = NULL;

    assert(init_key_ != NULL);
    delete] init_key_;
    init_key_ = NULL;
}

/**
 * Initializes the Mersenne Twister with a seed.
 *
 * \param s seed
 */
void MersenneTwister::init_genrand(unsigned long s)
{
    mt_[0]= s & 0xffffffffUL;
    for (mti_=1; mti_<N; mti_++) {
        mt_[mti_] = 
	    (1812433253UL * (mt_[mti_-1] ^ (mt_[mti_-1] >> 30)) + mti_); 
        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
        /* In the previous versions, MSBs of the seed affect   */
        /* only MSBs of the array mt_].                        */
        /* 2002/01/09 modified by Makoto Matsumoto             */
        mt_[mti_] &= 0xffffffffUL;
        /* for >32 bit machines */
    }
    // Store the seed
    s_ = s;
    seeded_by_array_ = false;
    seeded_by_int_ = true;
}

/**
 * Seed the Mersenne Twister using an array.
 *
 * \param init_key an array for initializing keys
 * \param key_length the length of \a init_key
 */
void MersenneTwister::init_by_array(unsigned long* init_key, int key_length)
{
    // Store the key array
    int i, j, k;
    init_genrand(19650218UL);
    i=1; j=0;
    k = (N>key_length ? N : key_length);
    for (; k; k--) {
        mt_* = (mt_* ^ ((mt_[i-1] ^ (mt_[i-1] >> 30)) * 1664525UL))
          + init_key[j] + j; /* non linear */
        mt_* &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
        i++; j++;
        if (i>=N) { mt_[0] = mt_[N-1]; i=1; }
        if (j>=key_length) j=0;
    }
    for (k=N-1; k; k--) {
        mt_* = (mt_* ^ ((mt_[i-1] ^ (mt_[i-1] >> 30)) * 1566083941UL))
          - i; /* non linear */
        mt_* &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
        i++;
        if (i>=N) { mt_[0] = mt_[N-1]; i=1; }
    }

    mt_[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 

    // Store the seed
    if (init_key_ != NULL) {
        delete] init_key_;
    }
    init_key_ = new unsigned long[key_length];
    for (int k = 0; k < key_length; k++) {
        init_key_[k] = init_key[k];
    }
    key_length_ = key_length;
    seeded_by_int_ = false;
    seeded_by_array_ = true;
}

/**
 * Generates a random number on [0,0xffffffff]-interval
 *
 * \return random number on [0, 0xffffffff]
 */
unsigned long MersenneTwister::genrand_int32(void)
{
    unsigned long y;
    static unsigned long mag01[2]={0x0UL, MATRIX_A};
    /* mag01[x] = x * MATRIX_A  for x=0,1 */

    if (mti_ >= N) { /* generate N words at one time */
        int kk;

        if (mti_ == N+1)   /* if init_genrand() has not been called, */
            init_genrand(5489UL); /* a default initial seed is used */

        for (kk=0;kk<N-M;kk++) {
            y = (mt_[kk]&UPPER_MASK)|(mt_[kk+1]&LOWER_MASK);
            mt_[kk] = mt_[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
        }
        for (;kk<N-1;kk++) {
            y = (mt_[kk]&UPPER_MASK)|(mt_[kk+1]&LOWER_MASK);
            mt_[kk] = mt_[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
        }
        y = (mt_[N-1]&UPPER_MASK)|(mt_[0]&LOWER_MASK);
        mt_[N-1] = mt_[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];

        mti_ = 0;
    }
  
    y = mt_[mti_++];

    /* Tempering */
    y ^= (y >> 11);
    y ^= (y << 7) & 0x9d2c5680UL;
    y ^= (y << 15) & 0xefc60000UL;
    y ^= (y >> 18);

    return y;
}

/**
 * Generates a random integer on [0,0x7fffffff].
 *
 * \return a random integer on [0,0x7fffffff]
 */
long MersenneTwister::genrand_int31(void)
{
    return (long)(genrand_int32()>>1);
}

/**
 * Generates a random real number on [0,1].
 *
 * \return a random real number on [0,1]
 */
double MersenneTwister::genrand_real1(void)
{
    return genrand_int32()*(1.0/4294967295.0); 
    /* divided by 2^32-1 */ 
}

/**
 * Generates a random real number on 0,1).
 *
 * \return a random real number on 0,1)
 */
double MersenneTwister::genrand_real2(void)
{
    return genrand_int32()*(1.0/4294967296.0); 
    /* divided by 2^32 */
}

/**
 * Generates a random real number on (0,1).
 *
 * \return a random real number on (0,1)
 */
double MersenneTwister::genrand_real3(void)
{
    return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); 
    /* divided by 2^32 */
}

/**
 * Generates a random real number on 0,1) with 53-bit precision.
 *
 * \return a random 53-bit real number on 0,1)
 */
double MersenneTwister::genrand_res53(void)
{ 
    unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
    return(a*67108864.0+b)*(1.0/9007199254740992.0); 
} 
/* These real versions are due to Isaku Wada, 2002/01/09 added */

NULL is case sensitive, so check that it’s all uppercase. Want to paste your entire code file so I can try it in my VS?

It’s in my post above. It has a header too:


/**
 * mt.h: Mersenne Twister header file
 *
 * Jason R. Blevins <jrblevin@sdf.lonestar.org>
 * Durham, March  7, 2007
 */
#pragma once
#ifndef METRICS_MT_H
#define METRICS_MT_H

/**
 * Mersenne Twister.
 *
 * M. Matsumoto and T. Nishimura, "Mersenne Twister: A
 * 623-dimensionally equidistributed uniform pseudorandom number
 * generator", ACM Trans. on Modeling and Computer Simulation Vol. 8,
 * No. 1, January pp.3-30 (1998).
 *
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html.
 */
class MersenneTwister
{
public:
    MersenneTwister(void);
    ~MersenneTwister(void);

    double random(void) { return genrand_real1(); }
    void print(void);

    void init_genrand(unsigned long s);
    void init_by_array(unsigned long* init_key, int key_length);

    unsigned long genrand_int32(void);
    long genrand_int31(void);
    double genrand_real1(void);
    double genrand_real2(void);
    double genrand_real3(void);
    double genrand_res53(void);

private:
    static const int N                    = 624;
    static const int M                    = 397;
    // constant vector a
    static const unsigned long MATRIX_A   = 0x9908b0dfUL;
    // most significant w-r bits
    static const unsigned long UPPER_MASK = 0x80000000UL;
    // least significant r bits
    static const unsigned long LOWER_MASK = 0x7fffffffUL;

    unsigned long* mt_;                  // the state vector
    int mti_;                            // mti == N+1 means mt not initialized

    unsigned long* init_key_;            // Storage for the seed vector
    int key_length_;                     // Seed vector length
    unsigned long s_;                    // Seed integer
    bool seeded_by_array_;               // Seeded by an array
    bool seeded_by_int_;                 // Seeded by an integer
};

#endif // METRICS_MT_H


But no problems are reported in that file.

You can’t use NULL for a null pointer. Use nullptr instead.

Unless you’re planning on building on some funny platforms, #pragma once should remove the need to do the #ifndef METRICS_MT_H block.

So you also don’t have a precompiled header file. I’m not 100% on exactly how they work, but it’ll both speed up your builds and the UBT will throw an error without one. It must be your first include on every header file.

I suspect VisualAssist would make your life a ton easier. There’s a demo you can try out - see if it helps. I was lucky enough that work bought me a copy, but apparently it’s bog standard to own it in the C++ world.

I believe the precompiled header should be included at the start of the .cpp file, not the header.

Okay, now I can’t include “<cassert>” because:

Error 1 error : The first include statement in source file ‘E:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\MersenneTwister\mt.cpp’ is trying to include the file ‘cassert’ as the precompiled header, but that file could not be located in any of the module’s include search path.

Yep, see what we said about needing a precomputed header file. The plugin wizard created one for you - just use that. Basically put any headers you’re using into it and then include that file.

So I get the five following errors:


Error	1	error : The first include statement in source file 'E:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\MersenneTwister\mt.cpp' is trying to include the file 'cassert' as the precompiled header, but that file could not be located in any of the module's include search paths.	E:\UE4 Projects\RandGenLib\Intermediate\ProjectFiles\EXEC	RandGenLib

Error	2	error MSB3075: The command ""E:\Epic Games\4.9\Engine\Build\BatchFiles\Rebuild.bat" RandGenLibEditor Win64 Development "E:\UE4 Projects\RandGenLib\RandGenLib.uproject" -rocket -waitmutex" exited with code 5. Please verify that you have sufficient rights to run this command.	C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets	43	5	RandGenLib

3	IntelliSense: explicit type is missing ('int' assumed)	e:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\MersenneTwister.h	3	1	RandGenLib

4	IntelliSense: class "MersenneTwister" has no member "GenerateMersenneTwisterArray"	e:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\RandomNumberGeneratorsPlugin.cpp	25	30	RandGenLib

5	IntelliSense: a value of type "int **" cannot be used to initialize an entity of type "const int"	e:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\RandomNumberGeneratorsPlugin.cpp	27	16	RandGenLib

6	IntelliSense: expression must have a constant value	e:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\RandomNumberGeneratorsPlugin.cpp	28	13	RandGenLib

7	IntelliSense: no instance of function template "ArrayCountHelper" matches the argument list
            argument types are: (<error-type>)	e:\UE4 Projects\RandGenLib\Plugins\RandomNumberGeneratorsPlugin\Source\RandomNumberGeneratorsPlugin\Private\RandomNumberGeneratorsPlugin.cpp	46	19	RandGenLib



My RandomNumberGeneratorsPluginPrivatePCH.h file:


// Some copyright should be here...
#pragma once

#include "../Public/RandomNumberGeneratorsPlugin.h"
#include "../Private/MersenneTwister.h"
#include "../Private/MersenneTwister/mt.h"
#include "UnrealTemplate.h"
#include <cassert>

My RandomNumberGeneratorsPlugin.cpp file:


// Some copyright should be here...

#include "../Private/RandomNumberGeneratorsPluginPrivatePCH.h"
#include "../Public/RandomNumberGeneratorsPlugin.h"



#define LOCTEXT_NAMESPACE "FRandomNumberGeneratorsPluginModule"

void FRandomNumberGeneratorsPluginModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
	
	
}

void FRandomNumberGeneratorsPluginModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
	
	
}

TArray<int> MersenneTwister::GenerateMersenneTwisterArray(int* NumberOfEntries)
{
	const int N = &NumberOfEntries;
	double ran[N];
	double mean = 0.0;

	// Initialize a Mersenne Twister
	MersenneTwister mt;

	// Take N draws from Uniform(0,1)
	for (int i = 0; i < N; i++) {
		ran* = mt.random();
	}

	// Calculate the mean
	for (int i = 0; i < N; i++) {
		mean += ran*;
	}
	mean /= N;

	TArray<int32> tArr;
	tArr.Append(ran, ARRAY_COUNT(ran));

	return tArr;
}



#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FRandomNumberGeneratorsPluginModule, RandomNumberGeneratorsPlugin)

My MersenneTwister.h file:


#pragma once

UCLASS()
class MersenneTwister : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()
	UFUNCTION(BlueprintPure, Category = "RandomNumberGeneratorsPlugin", meta = (FriendlyName = "Mersenne Twister", CompactNodeTitle = "->", Keywords = "Mersenne Twister RNG Random Number Generator Math"))
		static TArray<int> GenerateMersenneTwisterArray(int* NumberOfEntries);
};


Nothing? :c

Beyond my ability to solve I’m afraid. Be patient, someone good at C++ will wander along soon :slight_smile:

Actually, just a thought: take the <cassert> out of the PCH and put it back in your cpp file, but after the PCH include.

Not sure if I’m doing it right or not, but I put every header from my codebase that I’ve written into the PCH, then include it again in the actual CPP or header file. But I only put code I wrote into the PCH.

As I said, ignore the Intellisense errors. What often happens is that one thing goes wrong, and that problem causes several other errors to appear. The idea is to always solve from the top of the error list onwards - oftentimes, after fixing the first one, the rest disappear :slight_smile:

In regards to the first one - it’s saying that the first #include in your RandomNumberGeneratorsPlugin\Private\MersenneTwister\mt.cpp file isn’t the PrivatePCH. Every single .cpp file in your project has to start with an include to your PrivatePCH. If you don’t, it will try to include whatever you put instead as the PrivatePCH, which in this case is probably ‘cassert’ (based on the error, at least - I can’t see mt.cpp obviously).

If you can’t add <iostream> and other native headers there’s something wrong with your VS/C++ redist installation.
As said above, PrivatePCH must be the first header for every and all .cpp files that include or are included by your UClasses.
And, you use GENERATED_UCLASS_BODY macro, but you never define any ObjectInitializer for any of the UClasses you’ve paste code so far. If you don’t want to build initializer yourself, use GENERATED_BODY() instead.

Okay. I’ll try that out and return. I’m sure I’ll have other issues afterwards. Thanks so far guys.

I’ve now taken the entire project and zipped up. I hope someone can spot where I’m going wrong.
Last night I tried to add the PCH file to all my C++ and H files but when I put it in some, it works, when I put it in others it can’t open the file. Some times given it a path like “…/Private…” helps but other times nothing helps at all and I’m just left with frustration over why it can’t read a file that I give it direct pointers to.

http://www.filedropper.com/randgenlib

I don’t hope it’s too much trouble…I’d appreciate it a lot.