diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index b120b37f1fef05487fb267e0231dfef04e78cbf0..13b0cc419c6eb5c98dc6df48d2ecb2bcfe59e9ec 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -42,8 +42,6 @@
 #include <grpc++/impl/codegen/service_type.h>
 #include <grpc++/impl/codegen/status.h>
 
-extern "C" void* grpc_call_arena_alloc(grpc_call* call, size_t size);
-
 namespace grpc {
 
 class CompletionQueue;
@@ -69,7 +67,8 @@ class ClientAsyncResponseReader final
                                            const W& request) {
     Call call = channel->CreateCall(method, context, cq);
     ClientAsyncResponseReader* reader =
-        new (grpc_call_arena_alloc(call.call(), sizeof(*reader)))
+        new (g_core_codegen_interface->grpc_call_arena_alloc(call.call(),
+                                                             sizeof(*reader)))
             ClientAsyncResponseReader(call, context);
 
     reader->init_buf_.SendInitialMetadata(context->send_initial_metadata_,
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index a5f762e21da0c58abdef34df092d2dacf6419d64..90bb6584555da2dea61bc29d49240e3b76ae398e 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -66,6 +66,7 @@ class CoreCodegen : public CoreCodegenInterface {
 
   void grpc_call_ref(grpc_call* call) override;
   void grpc_call_unref(grpc_call* call) override;
+  virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) override;
 
   void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
 
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index a3df913c2648291808f2e381fb94aee8df55d91a..8833de0748d1563652065ae850c22285f2359d6b 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -96,6 +96,7 @@ class CoreCodegenInterface {
 
   virtual void grpc_call_ref(grpc_call* call) = 0;
   virtual void grpc_call_unref(grpc_call* call) = 0;
+  virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) = 0;
 
   virtual grpc_slice grpc_empty_slice() = 0;
   virtual grpc_slice grpc_slice_malloc(size_t length) = 0;
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index c2b5c6f450eb935c8b3b573fc9784b64db306304..88a7968b9b2b8df01cf526942c232594edc58c84 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -93,6 +93,9 @@ void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
 
 void CoreCodegen::grpc_call_ref(grpc_call* call) { ::grpc_call_ref(call); }
 void CoreCodegen::grpc_call_unref(grpc_call* call) { ::grpc_call_unref(call); }
+void* CoreCodegen::grpc_call_arena_alloc(grpc_call* call, size_t length) {
+  return ::grpc_call_arena_alloc(call, length);
+}
 
 int CoreCodegen::grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
                                               grpc_byte_buffer* buffer) {