Porting C++ to C++(.Net) Problem

S

Sebastian Sosna

Hello NG !

Iam developing in C# so my cpp knowledge is limited.
Ive downloaded a C++ sample wich is doing some AD Job. U can get it
here :
http://support.microsoft.com/?id=302515

Ive tried to port into C++ (.Net) and ran into errors wich i have no
clue whats this is about. After compiling the linker is throwing those
errors :

//////////////////////////////////////////////////////////////////////////////
CppGetGuids error LNK2020: unresolved token (0600004D)
CppGetGuids.Class1::GetGuids
CppGetGuids error LNK2020: unresolved token (0A000017) atexit
CppGetGuids error LNK2020: unresolved token (0A000023)
??_7type_info@@6B@
CppGetGuids error LNK2020: unresolved token (0A000024)
_CxxThrowException
CppGetGuids error LNK2020: unresolved token (0A00002D) _CrtDbgReport
CppGetGuids error LNK2020: unresolved token (0A000033) free
CppGetGuids error LNK2020: unresolved token (0A000035) memset
CppGetGuids fatal error LNK1120: 7 unresolved externals
//////////////////////////////////////////////////////////////////////////////

What i have done so far:
-Started a Class Library ( .Net ) Project.
-Copied the Code from Main.cpp to CppGetGuids.cpp
-changed from int wmain(.....) to void GetGuids
-declared this Method in CppGetGuids.h
-Added in the Project Settings under Linker/Input Options the
ActiveDS.lib and Adsiid.lib.
-Got rid of (...wchar_t *argv[ ], wchar_t *envp[ ]) instead
ive declared (...String __gc* argv[ ],String __gc* envp[ ])

well now iam here with no idea what the Problem could be.
Hope somebody is willing to help me.
Thanks!
See below the full code so far:



CppGetGuids.cpp:

// This is the main DLL file.
#include "stdafx.h"
#include "CppGetGuids.h"
#include <String.h>
//
// The following code segment illustrates how to enumerate all of the
controlAccessRight objects
// whose appliesTo property matches the SchemaIDGUID of the given
SchemaClass object
//
#define _WIN32_WINNT 0x0500
#define UNICODE


void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] )
{
//
// NO error checking is performed. If a call fails, the code
// will end ungracefully. Do not use this code as an example of
how
// to properly handle COM errors.
//
// The program expects 1 argument, a CN for a schemaClass object.
// if the object name is missing, the code will terminate very
ungracefully.
// a sample command line would like:
//
// code_executable "cn=SchemaClass_Object_Common_Name"
//
// Assuming of course, that this code was compiled into an
executable called
// code_executable.exe
//
// Be sure to include:
// ActiveDS.lib
// Adsiid.lib
// on the Link tab of the project.
//
HRESULT hr = E_FAIL;
//
// Very Important for ADSI interfaces to work proper, must
initialize COM
//
CoInitialize(NULL);
//
// Check for the correct number of arguments
//
if( argc < 2 )
{
// PrintUsage();
// return E_FAIL;
}
//
// Need to bind to the RootDSE to locate the Schema and
Configuration Containers
//
CComPtr<IADs> oRootDSE;
VARIANT vData;
VariantInit(&vData);
CComBSTR bConfigurationNamingContext;
CComBSTR bSchemaNamingContext;
CComBSTR bDefaultNamingContext;
hr = ADsGetObject(
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net/RootDSE", IID_IADs, (LPVOID
*)&oRootDSE );
if( FAILED( hr ) )
{
printf("Error %d occured opening RootDSE object\nTerminating
Program\n");
// return E_FAIL;
}
hr = oRootDSE->Get(L"defaultNamingContext", &vData);
bDefaultNamingContext.AppendBSTR( vData.bstrVal );
VariantClear(&vData);
hr = oRootDSE->Get(L"SchemaNamingContext", &vData);
bSchemaNamingContext.AppendBSTR( vData.bstrVal);
VariantClear(&vData);
hr = oRootDSE->Get(L"ConfigurationNamingContext", &vData);
bConfigurationNamingContext.AppendBSTR(vData.bstrVal);
VariantClear(&vData );
oRootDSE.Release();
//
// Build the ControlAccessRight object path from the given
Extended Right
// passed as the first argument
//

const wchar_t __pin* p = PtrToStringChars(argv[1]);

CComBSTR bArg = p ;
CComBSTR bSchemaClassPath =
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net";
bSchemaClassPath.AppendBSTR( bArg );
bSchemaClassPath.Append( L",");
bSchemaClassPath.AppendBSTR( bSchemaNamingContext);
CComPtr <IADs> oSchemaClass;
hr = ADsGetObject( bSchemaClassPath.m_str, IID_IADs, (LPVOID *)
&oSchemaClass);
if( FAILED(hr) )
{
printf("Unable to open SchemaClass object :\n%S\nReceived error
%d\nTerminating Program\n",
bSchemaClassPath.m_str, hr);
//
// CleanUp and exit
//
oRootDSE.Release();
CoUninitialize();
// return hr;
}
//
// Retrieve the SchemaIDGUID of the SchemaClass object.
// The GUID must be converted into the form of an AppliesTo
// attribute GUID.
//
// Convert the GUID to a string, and strip the "{}"'s
//
oSchemaClass->Get(L"SchemaIDGUID", &vData );
oSchemaClass = NULL;
WCHAR wszGUID[40];
WCHAR *pwsz;
SAFEARRAY *pRefGUID;
SafeArrayAccessData( vData.parray, (VOID **)&pRefGUID);
StringFromGUID2( (REFGUID)*pRefGUID, wszGUID, 40 );
for( pwsz = wszGUID; *pwsz; pwsz++)
{
switch (*pwsz)
{
case '{':
break;
case '}':
*(pwsz-1) = (WCHAR)NULL;
break;
default:
*(pwsz-1) = *pwsz;
}
}
CComBSTR bAppliesToGUID = wszGUID;
//
// Time to do a bit of clean up. We are done with
// the safe array, the schemaIDGuid variant (vData) and
// the Schema Class object SO:
//
// Be sure to release the raw GUIDs safe array.
// Clear the variant AND
// Release the SchemaClass object
//
SafeArrayUnaccessData( pRefGUID );
VariantClear(&vData);
oSchemaClass.Release();
//
// Now, bind to the Extended Rights Container and retrieve an
IDirectorySearch
// interface to prepare for the LDAP search....
//
CComBSTR bExtendedRightBindString = L"LDAP://CN=Extended-Rights,";
bExtendedRightBindString.AppendBSTR( bConfigurationNamingContext);
CComPtr <IADs> oIADsExtendedRights;
hr = ADsGetObject( bExtendedRightBindString.m_str, IID_IADs,
(LPVOID *)&oIADsExtendedRights);
CComQIPtr <IDirectorySearch, &IID_IDirectorySearch> oSearch(
oIADsExtendedRights );
oIADsExtendedRights.Release();
//
// Build the LDAP query string that will look something like:
// LDAP Server : bDefaltNamingContext
// LDAP Query String:
(&(objectclass=controlAccessRight)(AppliesTo=MODIFIED_SCHEMAIDGUID))
// LDAP Properties to return: CN
// Search Properties: Paged Search
// Search Scope: Sub Tree ( from the schema container and beyond)
//
//
// Build the query string...
//
CComBSTR bLDAPQueryStr;
bLDAPQueryStr = L"(&(objectclass=controlAccessRight)(AppliesTo=";
bLDAPQueryStr.Append( bAppliesToGUID );
bLDAPQueryStr.Append(L"))");
//
// Setup the Attributes and search preferences
//
// Perform a subtree search
//
ADS_SEARCHPREF_INFO prefInfo[2];
prefInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//
// Set the maximum records returned to 1000 ( maximum for AD )
//
prefInfo [1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE ;
prefInfo [1].vValue.dwType = ADSTYPE_INTEGER;
prefInfo [1].vValue.Integer = 1000;
//
// bind the search preferences with the IDirectorySearch object...
//
hr = oSearch->SetSearchPreference( prefInfo, 2);
//
// Prepare a list of attributes to return in the query...
// in our case, we want the Common Name only...
//
LPWSTR pszAttr[] = { L"cn"};
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
//
// Execute the LDAP Query....
//
hr=oSearch->ExecuteSearch(bLDAPQueryStr.m_str, pszAttr, dwCount,
&hSearch );
if (!SUCCEEDED(hr))
{
printf("LDAP Search failed with error %d\nTerminating
program\n", hr );
//
// Clean up
//
oSearch.Release();
// return hr;
}
//
// Now enumerate the result
//
ADS_SEARCH_COLUMN col;
// "0---------1---------2---------3----5"
BOOL bFirstTime = TRUE;
while( oSearch->GetNextRow(hSearch) != S_ADS_NOMORE_ROWS )
{
// Get attributes
//
// CN
//
hr = oSearch->GetColumn( hSearch, pszAttr[0], &col );
if ( SUCCEEDED(hr) )
{
if( bFirstTime )
{
printf("controlAccessRight ( Extended Rights) objects
associated with SchemaClass object: %S\n", argv[1]);
bFirstTime = FALSE;
}
printf("%S\n",(LPWSTR)col.pADsValues->CaseIgnoreString);
oSearch->FreeColumn( &col );
}
}
oSearch->CloseSearchHandle( hSearch );
oSearch.Release();
CoUninitialize();

// return 0;
}
//////////////////////////////////////////////////////////////////////////////

// CppGetGuids.h:

#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <stdio.h>
#include <atlbase.h>
#include <objbase.h>
#include <activeds.h>
#include <winnt.h>
#include <sddl.h>
#include < vcclr.h >
#include <stdlib.h>

#pragma once

using namespace System;

namespace CppGetGuids
{
public __gc class Class1
{
// TODO: Add your methods for this class here.
void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] );



};
}

////////////////////////////////////////////////////////////////////////////
stdafx.cpp :
// stdafx.cpp : source file that includes just the standard includes
// CppGetGuids.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"


/////////////////////////////////////////////////////////////////////////////

resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc

#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
 
G

Guest

You GetGuids error is because in the header you have declared the function as part of a class, but in the source file you have definined the function as global. The definition should look like this
void CppGetGuids::Class1::GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ]

The remaining errors are problems with your include statements. I havn't gotten <String.h> and .Net to play nicely in the same file. You might want to consider dropping the #include <String.h> line. I think it would be easiest. I havn't used all of the headers you have. You may want to try to remove some and see if you can get away without them. You can also try including these headers before the #using <mscorlib.dll> statement or before any using namespace statements. As a final possibility you can create files which have no managed code and don't have any #using statements, that should have no trouble includeing these files. What is happening is the linker thinks these headers are managed code and is therefore looking for managed symbols. The symbols are contained in the CRT as unmanaged symbols, so they can not be found
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top