Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
689 views
in Technique[技术] by (71.8m points)

makefile - Linker errors in C program: LNK2019 and LNK1120

Following my previous question here : Compile a C library with Visual Studio 2010 ; I have a C project, with a source file I can't meaningfully change.

After fixing the previous problem, I now have two more errors:

error LNK2019: unresolved external symbol _random referenced in the function _fisher_yates myfile.obj
error LNK1120: 1 unresolved external myproject.dll

The line refering to _random is this:

j = i + random() % (nb - i);

I'm guessing that random() is not part of the standard C/C++ libraries ?

A colleague has suggested looking at the makefile for the included libraries to see what would be missing. I have found this:

LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static

and a bit further:

LIBS = $(LIBRUBYARG_SHARED)  -lshell32 -lws2_32 -limagehlp -lshlwapi  

At the top of my c file, I have added:

#ifdef _MSC_VER
#define inline __inline
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "imagehlp.lib")
#pragma comment(lib, "shlwapi.lib")
#endif

But I still get the same error, so I guess it's the LIBRUBYARG_SHARED that's the cause of the problem. I don't even know what it is ; the makefile is generated through 'mkmf'.

As you may notice, I have no idea what's going on, and any help is appreciated.

Thanks !

Update

In the #ifdef _MSC_VER section I have added a #define random rand instruction. While rand() is not safe, this has nothing to do with security (it's to shuffle objects on screen), so I think it will be enough.

Update 2

Actually just "binding" random to rand is not enough, because rand returns always the same value if not used with srand. So, following this article, I have written my own random() function:

#ifdef _MSC_VER

// fix: the Visual Studio 2010 C compiler doesn't know "inline" but knows "__inline".
// see: https://stackoverflow.com/a/24435157/2354542
#define inline __inline

#include <Windows.h>
#include <wincrypt.h>

/// Visual C++ 2010 is not POSIX compliant :'( so I have to code a random() method
/// https://www.securecoding.cert.org/confluence/display/seccode/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers
long int random() {
    HCRYPTPROV prov;
    if (CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) {
        long int li = 0;
        if (CryptGenRandom(prov, sizeof(li), (BYTE *)&li)) {
            return li;
        } else {
            // random number not generated
            return 0;
        }

        if (!CryptReleaseContext(prov, 0)) {
            // context not released
            return 0;
        }
    } else {
        // context not created
        return 0;
    }
}

#endif
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

you may use rand() function, its part of stdlib


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...